Monthly Archives: February 2012

A quick and easy way to deploy from git with post-receive hooks

I’ve recently moved over to a custom framework for my main website and wanted deployments into the repositories release branch to be seamless. I could use Jenkins but that would probably be overkill.

To accomplish this, I wrote a quick post-commit post-receive script that will be called by git each time a commit is pushed into my repository. If the branch name matches ‘release’ the commit is extracted into a release folder under the webroot. The webroot directory (in reality a symbolic link) is then updated to point to this new release.

Using symbolic links has the advantage of not leaving your website in an inconsistant state as files are deleted and then re-extracted, it should be an atomic operation.

Here’s the script, put this in your git repository under the hooks subdirectory in a file named ‘post-commit’.
The old revision, new revision and branch name are handily passed into this script :)

Edit: One thing to keep an eye out for is that if you are running PHP5-FPM, when the symbolic link is switched to the new location the fpm seems to be still serving your scripts from the old location. I would love to figure out why this is but a workaround is to call /etc/init.d/php5-fpm restart as the final step in the post-receive script (not ideal!!)

# A post commit hook that takes any updates pushed to the 'release' branch
# and creates a release directory for the new version under the webroot.
# Live site is then symlinked to this new release directory.
# this is the root of the website (a symlink to a release directory)
if [ "$branch" == "release" ]
    # create a release directory to extract files into
    mkdir $target
    echo "Making target directory: $target"
    # create an archive in the webroot of
    /usr/bin/git archive master --format zip --output $target/
    echo "unzipping archive..."
    # extract the archive
    unzip -o -q $target/ -d $target
    echo "removing deployment archive"
    # remove the archive file
    rm $target/
    echo "switching symbolic link to $target"
    # now switch the live site to point to the new release
    ln -nsf $target $webroot
    echo "done";