Simple Git Auto Deployment to Digital Ocean or any other VPS

I have been using Digital Ocean VPS for couple of years now. I am always editing my websites even their technology stack has changed back and forth multiple times. I have always used FileZilla to transfer my code from local to remote repository. This is not efficient way and while searching for better way of autodeployment I came across an article by Digital Ocean itself for using git for deployment. This article recommended using beta directory for testing and then deploying to your primary directory. I thought it is not required for small and single developer websites so I thought to create a simple structure.

Here we will have only two repositories

  • Local repository where I will be making changes
  • Remote repository on Digital Ocean droplet from where my live website will run

Step#1 Install git on local and remote machine.

Installing git

$sudo apt-get install git

Step#2 Initiate Git repo

On Local machine cd to folder having your code and then initiate git repo as below

$git init

On remote server, cd to directory which will host your code and then initiate git repo

$git init --bare

Please note the difference : A bare repository is a git repository without a working copy, therefore the content of .git is top-level for that directory.

Use a non-bare repository to work locally and a bare repository as a central server/hub For example, when you create a repository on github.com, it is created as a bare repository.

To conclude, the repository on the server side is going to get commits via pull and push, and not by you editing files and then committing them in the server machine, therefore it is a bare repository.

You can push your changes from local to remote by using following command

Step#3 Add remote repository

You can add remote repository using below command.

$git remote add live ssh://user@domain.com/var/www/foldername

Here instead of domain.com you can use your droplets ip as well.

Once this is added you can check your remotes using following command

$ git remote -v
live ssh://user@mydomain.com/var/www/foldername (fetch)
live ssh://user@mydomain.com/var/www/foldername (push)

Step#4 Deploying the changes.

Once your changes are ready, you can deploy it using following commands

git add .  
git commit -m "1st commit"  
git push live master  

Step#5 Verify the changes

You can log in to your droplet and check if your code is updated. You can do this by simply verifying the files.

Troubleshooting

I faced an issue that my local repo was pushing files successfully but remote git repo was not updated.  To check if git changes were actually pushed or not run following command

$git log

This will show list of changes pushed to remote. If you see your changes are pushed but still not reflected, you need to run following manually

GIT_WORK_TREE=/var/www/foldername git checkout -f

Obviously, you should not run above command manually every time you make the change as this will loose the whole purpose of deployment automation.

cd to hooks folder, create post-receive file and add above line into file

cd hooks/
sudo nano post-receive

Once file is created, change the file permissions as below


sudo chmod a+x post-receive

And now you are all set. Going forward, any change that you push will be reflected on your remote repository.

Important Note: Depending on your changes and the type of application that you are hosting, you might have to restart the server to have these changes reflected on your website.

Github commits linked to the wrong user [Solved]

I have been using my Ubuntu desktop for a long time and all my commits were getting deployed to github remote repo without any issue. Few days back, someone else used my machine for few days. Now when I am pushing any code to guthib, its asking my for credentials but when I am checking my github repository, a different users name is displayed.

check current user configured by following command

$ git config --global --list
user.name=FirstName LastName
user.email=FirstName.LastName@gmail.com
push.default=simple

We need to change it. It can be changed by two ways

  1. By editing .gitconfig file

.gitconfig is located in your home directory. File content is as below

[user]
     name = FirstName.LastName@gmail.com
     email = FirstName.LastName@gmail.com
[push] 
    default = simple

You can simply edit the file to required name and email.

You can open this file using following command as well


git config --global -e

2.  Changing details using command line

git config --global --unset-all user.name
git config --global --unset-all user.email

You can add required details as below

git config --global --add user.name <YourGithubUserName>
git config --global --add user.email <YourGithubemail>

if you want to change user names without resetting


git config --global user.name <YourGithubUserName>
git config --global user.email <YourGithubemail>

How to clone gist

Gist is one of the most efficient way to share code snippets, single files and full applications with other people. However one disadvantage of gist is that you can’t share directories, but this is not a major issue considering gist is primarily used to share code snippets.

If you want to make local changes to a gist and push them up to the web, you can clone a gist, make changes and then make commits. It is exactly same process as you would with any Git repository.

Let us look at how to clone gist repository using https

Go to gist repository and get https link. Please find below image to see howto get the https link.

Using following command to clone repository

$ git clone https://gist.github.com/820c117b75d52514b2e58008be07a6eb.git
Cloning into '820c117b75d52514b2e58008be07a6eb'...
remote: Enumerating objects: 44, done.
remote: Total 44 (delta 0), reused 0 (delta 0), pack-reused 44
Unpacking objects: 100% (44/44), done.
Checking connectivity... done.

That is it. You are done. You can cd into the folder and check the files.

How to publish code to gist repo along with github repo

Previously I was keeping code in the same post and I was using code formatting add-ons but then I realised this is very inefficient. While searching for best way to add code to post, I discovered Github gist. It is very useful to add code snippets to blog.

However, while using gist, I stumble across a problem. I had to maintain same code at two places, one on github repository and second on gist. Many times, I was updating my old code, now this lead to problem of updating same two at two places. Github repository was getting updated by git push however, I had to manually updated gist. I did not spend much time to find solution as it was not taking much time, nonetheless this was awkward and I made a mental note to find a workaround sometime later.

Today I did a bit research and found couple of methods. Following is the most efficient method that I found.

Step#1 Create your Github repo as usual.

Please check the post Publish local repository to Github using https for creating local repository for your Github repository

Step#2 Create a Gist repository and add this as another remote

Gist are nothing but repository only. Create gist repository from https://gist.github.com/

Gist name will be first file name that you will create. Keep the first file name same as that of Github repo whose copy you want to maintain as Gist.

Now we need to add this repository as remote with name gistrepo on your local repository. I chose to add gistrepo using https as this is easiest, you can get this link as below

Use following command to add remote gistrepo

git remote add gistrepo https://gist.github.com/43XXXXXXXXXXXXXXXXXXX2.git

You can check remote by using following command

$ git remote -v
gistrepo https://gist.github.com/43e731ef9297ecfe4d727831a5e75a22.git (fetch)
gistrepo https://gist.github.com/43e731ef9297ecfe4d727831a5e75a22.git (push)
origin https://github.com/conquistadorjd/python-07-ml.git (fetch)
origin https://github.com/conquistadorjd/python-07-ml.git (push)

Step#3 Push changes to gistrepo after pushing changes to origin i.e. github repo

First push changes to your Github repository.

$ git add .
$ git commit -m "test changes"
$ git push -u origin master
Username for 'https://github.com': conquistadorjd
Password for 'https://conquistadorjd@github.com': 
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 1.49 KiB | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/conquistadorjd/python-07-ml.git
c813187..5c0472f master -> master
Branch master set up to track remote branch master from origin.

Once done, push these changes to your gistrepo repository. While pushing the changes, please make sure you use -f instead of -u.

$ git push -f gistrepo master
Username for 'https://gist.github.com': conquistadorjd
Password for 'https://conquistadorjd@gist.github.com': 
Counting objects: 12, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (10/10), done.
Writing objects: 100% (12/12), 2.59 KiB | 0 bytes/s, done.
Total 12 (delta 4), reused 0 (delta 0)
remote: Resolving deltas: 100% (4/4), done.
To https://gist.github.com/43e731ef9297ecfe4d727831a5e75a22.git
+ cecff3f...5c0472f master -> master (forced update)

Now go and check your gist and Github, both will be in sync and wherever you have used the code, it will be get updated.

Git Quick Reference

Git is the most useful tool for developers but if someone does not use it for a while, it all seems confusing. Git is tricky. Here are some of the most commonly used command.

Installing git

$sudo apt-get install git

Create new git repository

$git init

Create git repository on server

$git init --bare

Please note the difference : A bare repository is a git repository without a working copy, therefore the content of .git is top-level for that directory.

Use a non-bare repository to work locally and a bare repository as a central server/hub For example, when you create a repository on github.com, it is created as a bare repository.

To conclude, the repository on the server side is going to get commits via pull and push, and not by you editing files and then committing them in the server machine, therefore it is a bare repository.

You can push your changes from local to remote by using following command

$git remote add live ssh://user@domain.com/var/www/foldername

once this is added you can check all remotes using following command

$ git remote -v
live ssh://user@mydomain.com/var/www/foldername (fetch)
live ssh://user@mydomain.com/var/www/foldername (push)

Deploying the changes.

Once your changes are ready, you can deploy it using following commands

git add .  
git commit -m "commit comment"  
git push live master  

Copy remote repository to your local folder.

$git clone ssh://abc...xyz.git/  

To get list of files changed in directory

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)

modified: MySQL/MySQL_Select.py

Untracked files:
(use "git add <file>..." to include in what will be committed)

MS Excels/xlsx_read_into_pandas.py
MySQL/MySQL_update.py
image/

no changes added to commit (use "git add" and/or "git commit -a")

Get commit history

$git log