Keeping a Drupal Site Updated

I had an hour or so to kill on my train ride home from DrupalCamp Chicago so I took advantage and updated the code powering this site. It's not uncommon for a site's code to sit stale for a few months--or more-- and fall behind on the recommended releases of Drupal core and the contributed modules and it's normally not a huge deal, but from time to time security releases come out and you should handle those as soon as possible by upgrading or otherwise mitigating the vulnerability.

Before I jump into the steps I took to upgrade, let's discuss the status of the site before the upgrade. It runs Drupal 7 and is a few releases behind, but it will be only a minor version upgrade. There were also a dozen or so contrib modules falling behind. After looking at the list, I determined most of the upgrades would be seamless but a few I thought had potential for hiccups.

Updated Features Configuration

It seems that no matter how diligent I am, some bit of configuration gets changed in production which overrides my Features configuration. The first thing I did was got an exact copy of the production site (code and database) running locally in order to update the underlying Features. Once those were at default status I gave a quick look over the remaining components and built those configurations into my existing Features. Now that my configuration was at a default status, I pushed that all live and made sure that my exportable components (Views, Contexts, etc) were stored only in the Features code and not in the database.

Upgraded Core

Next I upgraded the Drupal core code to the latest version. Since I initially cloned my repository from, all I needed to do to get the proper code (along with the change history) was to add's repository as a remote, fetch in the new git objects, and merge in the latest tag. After running update.php, clicking around a bit, and reviewing my error log everything looked fine so it was good to go. Commit.

Upgraded Contrib

Next I upgraded my contrib modules in 3 "phases."

  • Safe modules: An experienced Drupal developer can review a list of modules and have a good idea which ones can may be upgraded with confidence. Also being connected to the Drupal community through professional engagements, social events, social media, and IRC one gets wind of issues as they arise. For these safe modules, I just pulled the trigger and update dvia Drush in one fell swoop. Some quick user testing and I determined all had gone well. Commit.
  • Risky modules: The opposite of the safe modules are ones that seem risky. These may have a reputation for causing headaches, are not widely-used, have complex functionality, or provide functionality that is very valuable to the site. For these I apply the upgrade, test, then commit one at a time. These incremental commits allow you to step back in the case of a failed upgrade instead of starting from step one.
  • Modules you don't want to update: There are a handful of legitimate reasons why you may choose to not update a module. Just remember if the upgrade contains a security release you're potentially exposing your site to an exploit so be sure to read and understand what the vulnerability is then mitigate as needed. In my case I chose not to update the Twitter module. I'm using it to power the sidebar on the site and it pull in tweets that I've favorited. In order to do that I am running a patched Twitter module. The patch never made it into the module and since the time I patched it it has been updated, but I'm not confident that my changes will apply to the new release. Maybe someday I'll re-roll it but for now it stays put.

Upgraded and Rebuilt Features

Okay, minor fib--the fourth phase of updating contrib modules was upgrading the Features module. I held this until the end because I was moving from 7.x-1.x to 7.x-2.x, which contains major changes to the components provided by Features. So after everything else was in place I updated the Features module then went through and updated my Features module. I was then able to go back through and update Features configuration as necessary and rebuild the with the restructured components. This all went smoothly and I was able to get my config into code, committed, and ready to deploy.

Making It All Live

Pushing the updated code live is just like pushing any other code update. I pulled the new code into the production server, ran update.php, cleared the caches for good measure and everything went well. One last step was to review my Features configuration to make sure everything was default. Just like that my site is up to date, and my train has made it to my stop.

Happy updating!