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.

Backups

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 rake rails:freeze:gems

Environment configuration

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.

Common causes of path problems are any non-ruby libraries that are in use, such as ImageMagick (used by Paperclip), the Sphinx search engine (used by Thinking Sphinx), and many more.

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.

If you are using Capistrano and Passenger, here are some detailed instructions for setting up and deploying to multiple environments.