Here comes the post-receive git hook I used along with Octopress, to finish deploying the static blog server-side.

Introduction

What do we want to achieve ? Well, each time a new version of the static site, built by Octopress, is pushed to the git repository, we’d like git to copy it to the document root served by Apache (/srv/www/blog-test in this example).

In order to do that, we need to write a git hook, and to fiddle a little bit with permissions.

Git hook

We’re talking about a post-receive git hook. Here it is:

#!/bin/bash -e
#
# Git hook to finish deploying an Octopress website server-side.
#
# Each time the 'master' branch is updated, just clone it, and copy
# the content (aka the static website) to the location expected by
# the web server.
# Git must have the permission to write there.

REPO=$(basename "$(pwd)" | sed s/\.git$//)
TMPDIR=/tmp/$REPO
WWWDIR=/srv/www/$REPO

stdin=$(cat)
refs=$(echo "$stdin" | cut -d' ' -f3)

# Exit if nothing was pushed to the master branch
echo "$refs" | grep -q 'refs/heads/master' || exit 0

# Ensure the target directory is writable
[ -d "$WWWDIR" ] || echo "'$WWWDIR' doesn't exist !" && exit 1
[ -w "$WWWDIR" ] || echo "'$WWWDIR' is not writable !" && exit 1

# Clone the master branch, and copy the static website
[ -d "$TMPDIR" ] && echo "Removing '$TMPDIR'..." && rm -fr "$TMPDIR"
git clone . "$TMPDIR" --branch master && rm -fr "$TMPDIR/.git"
[ -d "$WWWDIR" ] && echo "Emptying '$WWWDIR'..." && rm -fr "$WWWDIR/*"
mv -v "$TMPDIR/*" "$WWWDIR"
rmdir "$TMPDIR"

There’s a few things to notice in this script:

  • the -e in the first line, to exit if an error happens
  • WWWDIR that you may change to suit your config
  • rm -fr here and there, so you’d better read and understand before running that wildly
  • echo commands are there for a good reason. Indeed, stdout is forwarded by git, and ends up in the console of the user that did the git push. Or more precisely, octopress deploy in our case.

Settling write permissions

After that, we just have a few ownership details to solve. As you can see in the script above, git will write inside the directory /srv/www/WWWDIR. We must manually create this directory, and allow git to write there. A solution is to add git to the group www-data (which is the user Apache is running), so that they can both access it.

First, let’s create the document root directory:

$ cd /srv/www
$ mkdir blog-test
$ chgrp www-data blog-test
$ chmod g+w blog-test
$ ls -l
total 4
drwxrwxr-x 2 root www-data 4096 Sep 29 19:08 blog-test

And now, just add git to the right group:

$ addgroup git www-data