Deploy application to production server using git and post-receive hook

20 November 2022

In this article we'll explore how to deploy on server (Linux VPS) with git and post-receive hook

If you want to automate deployment process from your localhost/dev environment to production server (and you don't want to manually transfer files via FTP) - the best way could be using post-receive hook.
You'll be able to deploy your app with single liner from your local machine:

git push prod master

To acomplish this we'll have to deal with 3 locations:

  • Localhost environment (e.g. /path/to/my-project)
  • VPS production environment (e.g. /var/www/html/my-project)
  • VPS git bare repository (e.g. /home/user)

For the sake of simplicity I'll assume that user is user from our production server

Localhost environment

This is our dev location, our code that we are developing on local machine is here. If we did not already initialized git repository we can do it now:

cd /path/to/my-project
git init

VPS production environment

Just create project folder:

mkdir /var/www/html/my-project

VPS git bare repository

On production server we'll create so called bare git repository, this repository will not contain working tree (just the con­tents of what is typ­i­cal­ly in the .git directory). This repository contains folder named hooks.
Inside of it we'll create new hook called post-receive:

cd /home/user/
mkdir my-project-repository
cd my-project-repository
git init --bare

Now, inside my-project-repository you'll find hooks folder, this is location where we'll create post-receive hook.

cd /home/user/my-project-repository/hooks
nano post-receive

The content of post-receive file:

#!/bin/sh

WORK_TREE="/var/www/html/my-project"
GIT_DIR="/home/user/my-project-repository"

# Checkout files:
git --work-tree="${WORK_TREE}" --git-dir="${GIT_DIR}" checkout -f master

Important:
We should chmod post-receive file so it can be executed:

chmod +x /home/user/my-project-repository/hooks/post-receive

This code will be excecuted after receiving push from your local machine, it will checkout master branch.
It could be extended with additional commands if needed. E.g. we could add extra line for process restart if we are working with node app.


Now, on our localhost we'll add this new repository to our git config.

cd /path/to/my-project
git remote add prod user@VPS_IP_ADDRESS:/home/user/my-project-repository

And this it it.
To test our work, let's add index.html inside root of our app and then add/commit and push our changes:

cd /path/to/my-project
touch index.html
git commit -am  "we just added some file"
git push prod master

After few moments we'll find new file index.html on our VPS server inside /var/www/html/my-project path.