Drupal Deployment with a Git post-receive hook

By: Nicholas Whittier 08/22/2012

Drupal deployment and maintenance often proves challenging when teams of developers are involved in a given Drupal project. A great way to reduce deployment pains is to use a distributed version control system, and integrate deployment efforts in your DVCS. As Drupal core is using Git, I am focusing on Git as a DVCS and using Git’s hooks to handle deployment. I’ll also point out that the Git hook deployment technique discussed here works for deploying many (most) web sites, but I am going to add details on drush and features modules, and get more specific to Drupal eventually (hence the title).

There are a lot of different ways to host Drupal, and I’m going to gloss over pros/cons and many of the techniques here (it’s another post). For now, I assume the following:

  • A web server capable of serving PHP is running.
  • You have server(s) representing at least staging and production (and development on a local machine).
  • Git is installed and configured locally and installed on your server(s).

I am going to demonstrate with the fake domain: drupaldeploy.com. I assume you either have DNS configured or hosts file entries to direct drupaldeploy.com and staging.drupaldeploy.com to the same server. On that server you have users ‘git’ and ‘drupaldeploy’. Your ssh public key (and keys for anyone who needs to deploy) is present in the /home/git/.ssh/authorized_keys file. I assume the ‘git’ user can write to the webroots and they are:

  • drupaldeploy.com: /home/drupaldeploy/drupaldeploy.com/html/
  • staging.drupaldeploy.com: /home/drupaldeploy/staging.drupaldeploy.com/html/

I assume your local git repository is initialized and populated with In your git repository, I am going to assume you are creating multiple branches and not working solely in master. I assume you have at least:

  • master – this is production
  • staging – this is for staging (almost ready for production, but likely needs review or QA)
  • development – where most of your development work occurs
  • etc. – feature branches and bug fixes (use these to keep the other three highly organized and relatively stable)

This certainly isn’t the only option for branching techniques, but it’s well organized and manages to keep important branches safe. I’m basing this model predominantly on the branching model at nvie.com. Now let’s get to it.

Create a git bare repository on the server

ssh git@drupaldeploy.com
mkdir ~/drupaldeploy.git
cd ~/drupaldeploy.git/
git init --bare

Add a remote repository on local and push to the server

cd /your/local/repo/
git remote add drupaldeploy git@drupaldeploy.com:/home/git/drupaldeploy.git
git push drupaldeploy master

The hook

Check to see what is being pushed, and deploy it to the appropriate location. On the server, create the /home/git/drupaldeploy.git/hooks/post-receive file (make sure it is executable by the ‘git’ user):

#!/bin/bash

read oldrev newrev refname

if [ $refname = "refs/heads/master" ]
then
  echo "### Deploy production"
  GIT_WORK_TREE=/home/drupaldeploy/drupaldeploy.com/html git checkout -q -f master
  
elif [ $refname = "refs/heads/staging" ]
then
  echo "### Deploy staging"
  GIT_WORK_TREE=/home/drupaldeploy/staging.drupaldeploy.com/html git checkout -q -f staging

fi

Now anyone on the team can make some changes to their local repository’s master or staging branch, pull from the bare repository to make sure they’re current, and then deploy updated code with:

git push drupaldeploy master

-or-

git push drupaldeploy staging

Additional Notes

It’s easy to expand this technique to allow Drupal (and module) core installation via git. In some circumstances (particularly if you are hacking core), running Drupal and module maintenance updates through git can ease the burden of maintenance on heavily customized sites.

If you are using the Features module (hint: you should be), feature updates can be committed and imported/updated via careful commit locations and updates to your git hook. This is made even easier if you are using Drush…

If you are using Drush, you can do awesome things like importing/updating Features (i.e., check for file presence in some directory, and if present execute ‘drush content import –file %filename’), or automatically clearing the cache whenever a web root update occurs (via ‘drush cc’).

Depending on your server config, it may also be appropriate to restart services. There are permissions considerations to account for, but restarting Nginx, Apache, PHP-FPM, Varnish, etc. can be handled in Git hooks.

Further Reading

http://toroid.org/ams/git-website-howto
http://www.adappt.co.uk/automated-deployment-drupal-using-git
http://wolfgangziegler.net/git_deploy_code_changes
http://joemaller.com/990/a-web-focused-git-workflow
http://nvie.com/posts/a-successful-git-branching-model
http://www.kernel.org/pub/software/scm/git/docs/githooks.html
http://git-scm.com/book/en/Customizing-Git-Git-Hooks

Leave a Reply




banner graphic

How can I be sure that I own the intellectual property and source code of my app?

I have a great idea for a mobile application, but I know nothing about designing and developing a mobile app and I want to make...

More questions and answers in The Advice Section

What Our Clients Are Saying

Web design and development seems to be a business relationship built on the “I’ve got something better philosophy”. As a longtime customer of Accella, I could not be more pleased. We went through a major transition in the past few months; the challenge of the project was not only accepted, but [Accella] seemed to revel in it. All time deadlines were hit with flying colors and the performance improved. We at BlueLine Rental are looking forward to the continued partnership.

Matt Tavianini
BlueLine Rental
(formerly Volvo Rents)

Get a Quote Contact Us