Coding Range

Deploying using Git Push

May 12th, 2014

All the cool kids are doing it, so why not take it out for a spin?

There seem to be plenty of over-complicated post-recieve hooks on Stack Overflow and various tutorials, but I wanted something nice and simple.

I store my web sites in /srv/www/<site name>, so that provides a nice and easy convention to base a deploy script on.

I put a bare git repository in /srv/deploy/<site name> and added the following post-receive hook:

#!/bin/bash

GIT_DIR=$(dirname $(dirname $(readlink -f $0)))
DEPLOY_DIR=/srv/www/$(basename $GIT_DIR)
git "--work-tree=${DEPLOY_DIR}" "--git-dir=${GIT_DIR}" checkout -f

Note: Remember to set the execute bits (chmod +x) on the hook script. I forgot to. 😔

This does the following:

  1. Read the path to the hook script file (readlink -f $0)
  2. Get just the directory from the script path (/srv/deploy/<site>/hooks)
  3. Get just the directory from the hook dir path (/srv/deploy/<site>) and store it as the GIT_DIR variable
  4. Get just the folder name of GIT_DIR (<site>) and build the DEPLOY_DIR path as /srv/www/<site>
  5. Check out a copy of the git repository working tree from GIT_DIR to DEPLOY_DIR.

Then to set up the push, I need to add a git remote as follows:

git remote add production <host machine>:/srv/deploy/<site>

Deploying becomes as easy as git push from the master branch. I think I can push from other branches too - which would be neat for staging - but I haven’t tried it yet.

The convention-based nature of this script means I can easily re-use the same script for every site. The same nature also makes it less readable. Yay tradeoffs!