I was recently asked how I deal with problems that come up between development and production environments, so here’s my answer. This article refers to apps that are currently deployed, not to deploying an app for the first time.
First, one of the best things you can do to make the deployment process easier is to automate it using Capistrano. I’m not going to get into the details of setting it up, but Capistrano takes the busywork out of deployment and other common server tasks. It also allows you to quickly and easily rollback changes when needed.
I’m sure you already have a fully automated, redundant, offsite backup system (you are backing up your database, right?). But especially before deployments, make sure that you have a fresh backup, and a good way to restore if things go wrong.
Be a good web citizen
Update the server at times of lower traffic and put up a maintenance page while the site is down, so anyone on the site during that time knows what’s going on. Depending on the audience and traffic level, you might warn users of the planned downtime beforehand.
Check your dependencies
Make sure that any dependencies within the application — gems, rails, ruby version — are the same. The easiest way to do this is to “freeze” the gems into the application’s vendor directory. Rails checks for frozen dependencies first, and if it doesn’t find them, it will fall back on whatever is installed at the system-level.
Freeze gems with
rake gems:unpack and freeze rails itself with
Check any environment-specific variables — especially paths to executables — that may not be the same on the production server. Anything that could be different should go in the respective
config/environments/(development or production).rb file instead of
config/environment.rb, which is loaded for all environments.
Setup a Staging environment
Rails makes it pretty easy to run different environments. Setting up a staging environment is the best way to be completely sure that you’re not going to break production.