Deploying Drupal updates onto a live site

Our configuration management discipline paid off last week, when we rolled out lots of bugfixes onto our production server. I used my deployment script to test the release-1 branch against our regression tests and copy the source code to the production server after it passed. A quick database update later, and everything worked without a hitch.

Why did it work? Here’s what’s behind our build system:

  • We have a branch for release-1 bugfixes and a trunk branch for new features. It’s easier than cherrypicking features to push to production.
  • Module .install files handle all behavior-related changes (variables, new modules, etc.). Drupal can automatically apply those changes during the database upgrade process. Even the process of enabling a module is done through an update function in our main module’s .install file. Note that the module install files are called in alphabetic order, so you may need to think about the sequence of functions.
  • The Simpletest framework for unit and functional testing allows us to write regression tests that minimize risks of updates.
  • Updates and tests are always run after a stripped-down copy of the production database is loaded, and are also occasionally tested against a full copy of the production database. This makes sure that the changes will cleanly apply to the production server. Domain Access complicates things a little because the domain name is encoded in the database, so my deployment script also takes care of substituting the correct domain name.
  • To automate testing and upgrades, we use the Drupal Shell (drush) module in our local and QA environments.
  • I wrote a deployment script webpage that provides a form for managing database changes and source code deployments to our QA server and to our production server.

I think it’s pretty darn good. What would make it even awesomer?

  • An updated deployment plan. I’m going to work on this document later.
  • Testing before commits, instead of after. maybe I can set up a pre-hook on my own system, or use Emacs to do this somehow.
  • Buttons to get full copy of database for local, QA. Full copies of the database take much more time, but are useful for getting a realistic feel for the functionality.
  • An article on how other people can get up and running with this kind of thing. DeveloperWorks, maybe?
  • http://agaricdesign.com/ Benjamin Melançon

    Article! Article! There is an awful lot there for people to learn from, especially the Drush and testing parts.

  • Katherine Senzee

    I second the motion. :) I’d really like to see details on the Domain Access chunk of the script. At the moment I’ve resorted to hard-coding my domains into /etc/hosts when I want to work locally. It’s not a pretty sight.

  • http://sachachua.com Sacha Chua

    Katherine: Use at least two, maybe three different domains, like local.whatever.com, qa.whatever.com, and whatever.com. Leave local.whatever.com defined in your /etc/hosts file, and then define a wildcard DNS entry for whatever.com. Set up multisites – sites/local.whatever.com and so on – and then configure $cookie_domain and other domain-specific variables in the appropriate settings.php

    The Domain Access module is optional. If you’re using it because you’re also doing domain-based editing control and shared content across domains, you’ll need to do a search-and-replace of the domain on the database dump before you load it into your database server. Also, it helps to override the domain_root variable in your settings.php.