How To Set Up Git Workflow For Web Application Deployment

What is Git?

Git is popular tool among developers. It’s mainly used to track changes in code through out the development process. But there is a hidden feature in it called Git hooks, through which we can run scripts when a specific event is triggered in a Git repository. One of these events is called Post-Receive.

What is Post-Receive Hook?

Post-Receive is an event which is triggered when there is a successful push to repository. This is useful in scenarios where an action has to be performed when a user commit s to the repository. We trigger this action by creating Post-Receive hook file in the repository.

Prerequisites

  1. SSH access to your server with super user (sudo) access
  2. Git is installed on the server
  3. Nginx server blocks / Apache virtual hosts enabled (optional - to verify the deployed website)

Refer tutorial on how to setup Nginx server blocks (Virtual Hosts) - Here

Create a Bare Git repository

Bare Git repository is a centralised repository where developers commit and fetch changes from it. In other words the repositories that you have created on Github are bare repositories and repository you have cloned on to your computer is a working directory for code development. TL;DR You can’t use bare Git repository for code development

When your web application is ready to be deployed to cloud, Login to your server via SSH and create the following directories to work with.

  • Login to server via SSH
ssh <user>@<vps>

Replace <user> with your ssh user id and <vps> with you server IP or fully qualified domain name (FQDN)

  • Create a folder to manage our bare Git repositories
sudo mkdir /repository
  • Change the permission of the directory to the logged in user
sudo chown -R $USER:$USER /repository
  • Create a bare Git repository
git init --bare /repository/example.com.git

Note: Ensure you are not creating these directories in default Nginx or Apache web root directories. As it would expose entire repository to public, if directory index listings are enabled.

Create a Post-Receive hook

  • Create a file named post-receive in the following path and make it executable
touch /repository/example.com.git/hooks/post-receive
chmod +x /repository/example.com.git/hooks/post-receive
  • Let us copy the below script and paste into post-receive hook file we created.
WEB_DIR="/var/www/example.com"
GIT_DIR="/repository/example.com.git"
BRANCH="master"

while read oldrev newrev ref
do
    # only check out the $BRANCH declared in the variable above
    if [ "$ref" = "refs/heads/$BRANCH" ];
    then
        echo "Ref $ref received, Deploying ${BRANCH} branch..."
        git --work-tree=$WEB_DIR --git-dir=$GIT_DIR checkout -f $BRANCH
    else
        echo "Ref $ref received. Only the ${BRANCH} branch may be deployed on this server."
    fi
done

Post-Receive script is triggered when a user makes a successful push to master branch on this server. The script checks the branch which the Git head is pointing into. If it matches the branch defined in the variable $BRANCH (I.e, master), Then it checks out a latest copy to the $WEB_DIR directory.

Add a new remote in Local Workspace

Let us log out from the server and cd into to the local workspace (website directory)

Warning: Don’t include any source code that contains private information that you do not want publish into the Git repository.

  • Let us initialise a Git repository (skip this step if Git is initialised)
cd /home/username/projects/example.com && git init
  • Create a new remote that points to your Git repository the server
git remote add production <user>@<server>:/repository/example.com.git

Note: Replace <user> and <server> with your ssh username and server IP / FQDN

Deploy your Web App

  • We have done configuring our repository and development workspace to publish the site by running the command
git push production master

Output

Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 286 bytes | 286.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Ref refs/heads/master received. Deploying master branch...
remote: Already on 'master'
To <vps>:/repository/example.com.git
   b46d132..0141515  master -> master

Voila! You have successfully setup Git workflow to deploy websites on Git push. You should see your static website or app deployed to the Nginx Web Root directory If you have followed this tutorial.

Tags