Deployment workflow with devel/live sites: 2011 version

Events happening in the community are now at Drupal community events on www.drupal.org.
pnijjar's picture

It's getting close to the time where I am going to release my first Internet-facing site (done in Drupal 6, mostly anonymous, with shared hosting). I am trying to figure out the best workflow for deploying the site in a way that will allow us:

  • To update content on the live site
  • To make structural changes on a development site
  • To sync those structural changes to the live site without losing content

I have been reading up on features and assorted threads on drupal.org, and it seems that davidwatson has a pretty good workflow listed on this thread: http://groups.drupal.org/node/56228#comment-161893 . But he is not using Features, and it seems to me that some of his steps (exporting Views, etc. and making database update hooks in a custom module) can be reduced by using Features.

Assuming that I am throwing source files into git, here is the workflow I am thinking of:

On staging site:

  • Pull DB from live site
  • Undo cache changes and boost
  • Make a git tag
  • Make structural changes
  • Run update.php if necessary
  • Update features module
  • Commit to git (and tag?)
  • Pull DB from live site again
  • Rerun update.php again if necessary
  • Test again

On live site

  • Put site into maintenance mode
  • Back up database and code
  • git pull
  • update features
  • run update.php
  • test and hope that things work
  • Take site out of maintenance mode

Here are my questions:

  • What should I have in my Features? I am thinking of using a monolithic Feature that has most of the modules and settings on my development site (not including things like Boost that should be different on the devel and live sites. How bad is this idea?

  • What should I NOT include in my Features?

  • What should I not commit to git? If there are cache directories I guess they should stay out. What else? Is it good practice to commit all modules (including the core install) to git?

  • How do I deal with settings.php? I think that cloning from development and then modifying files locally as a fork should work. Will it?

  • How do I deal with settings that should be different in devel and the live site? When I pull from the live site to do development, how can I script the configuration changes that will turn off caching/Boost? Is using a mysql script a bad idea? Should I be following davidwatson's lead and look into the Macros module?

  • What other things are likely to trip me up?

If you have a different/better workflow for deploying sites so they can be updated properly, please share them. I am worried that I am going to mess something up that will be a big headache to fix later.

Comments

A few suggestions to improve

deviantintegral's picture

A few suggestions to improve your process:

  1. Split settings.php into two files. Keep settings.php out of version control, and use it to store instance-specific settings. Any accounts, passwords, or API keys should be kept out of version control. Make it very small at first - it would probably just have your database configuration. At the end, do a PHP include to load 'settings.inc', which is stored in version control. Use it to store the bulk of settings.php. This also means that you can override variables for each site instance by using the $conf array. That will save you having to change any settings when you downsync from production.
  2. Consider keeping Boost on your staging site. Otherwise you could miss any bugs due to it being on production.
  3. Also consider using drush updatedb instead of update.php. Way faster and easier if you're already at the command line.
  4. For tags, I'd suggest doing just tags corresponding to pushes to production. Ideally configuration and code changes should only ever go from staging => production, so you shouldn't need to do a tag before you make changes.
  5. Use a separate branches for staging and production in git.

About Features - yes, you should absolutely use it. But be prepared for some modules to not be exportable without a patch. Using a monolithic feature can make it harder to debug issues. Keep your git commits of feature module updates small and descriptive (git add --patch is your friend), and try to avoid circular dependencies. A colleague of mine wrote this excellent article about Features: https://www.lullabot.com/articles/features-module

I'd be careful about the Macros module, as it records form submissions and replays them. IME, Features has been much simpler and more robust.

Thanks Andrew!

pnijjar's picture

As usual, I appreciate your advice. I had not thought about the settings.php split.

I am still confused about Features -- in particular about circular dependencies and how much I should be adding to Features. Here's a meta question: say I start using Features for the deployment and I mess something up. How much/what kind of pain is it going to be to recover?

Circular dependencies can

deviantintegral's picture

Circular dependencies can happen if say feature1 adds a content type, feature 2 adds a second content type sharing a field from the first content type, and you export a view containing both content types into feature 1. The idea is that you should when exporting new functionality into your features you ensure you don't have co-dependent modules.

The worst that can happen if you mess something up is that you have to re-create configuration. This almost always happens when you make changes in production instead of doing them in in code and deploying them. I suppose when you get into deleting fields or content types you could lose data, but it's no worse than without Features. Just make sure you have good backups and test your upgrade paths :)

Tentative solution

pnijjar's picture

At the Drupal meeting Khalid mentioned having a third version of the site that can be used to test changes before going live. I call this my "throwaway" site. This relieves the pressure a lot.

Now when I want to make a change, I pull the live database from production into my staging site. I have a couple of (conflicting) Features that help me transition from staging values to production values and vice versa (aggregating CSS/JS, etc.). So I pull the live database, activate the "Staging" feature, and then implement the new functionality. Once I am happy with it I attempt to figure out what can be put in code and what needs to be done live using my throwaway site. When I am convinced I have figured it out then I make the changes on the live site.

So far it is working, but these are early days. I am sure that everything will go pear-shaped soon.

Waterloo Region Drupal Users Group

Group organizers

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: