Making website upgrades seamless: script the changes

This post is more than 16 years old.

Posted at 17:06 on 24 April 2007

One of my tasks this week has been to roll out some changes to a fairly busy web application. Because it is pretty heavily used, when we make changes we need to get it right and minimise downtime.

How do you do this? Script the upgrade process. Ideally, you should be able to simply copy a working build to the production server, hit a button (or run a script) to switch from the old version to the new one, and you're done.

This particular web application's upgrade process is very simple. You get the code files from the build that you want to deploy and copy them onto the web server -- into a new directory for each version, e.g. "html-3.14". You change a symbolic link at the web application's root that points to the version you want to use. You're done. Rolling back -- should things go pear-shaped -- is simply a case of changing the symlink back again.

To get this working effectively, I had to streamline the application itself. Some files, such as site configuration, may vary from one server to the next, so I had to separate these out. I partitioned the application into three directories: the code, the configuration files, and dynamic data, such as logs and uploaded files.

Only the code directory changes between versions: its contents are exactly the same whether they are on the developer's machine, the staging server or the live server, and it has no special requirements in terms of access rights or contents. Files that need to vary between different servers (such as configuration files) are kept in a separate directory and are not changed during a normal upgrade process. This makes the upgrade script very simple.

This explanation is probably a little bit simplistic, although it can easily be extended to take account of extra requirements such as changes to the database schema or addition of new configuration options. Some upgrades will also have much more complex requirements, but the general principle is the same. Script the upgrade process so that it runs in a single step. It's the same principle as the one Joel Spolsky makes when he asks in The Joel Test, "Can you make a build in one step?" If you have to edit several files and jump through several hoops, the risk increases that you will make a mistake somewhere along the line. Being able to do it all in a single step is much more robust, and mostly seamless from the end user's perspective, because if all goes well, they will notice no downtime, but only that there are some new features and some irritating bugs have been fixed.