Posted by & filed under Deployment, Rails.

The following describes one method of deploying Rails applications in a production environment. I have only used this approach with a single server, and some changes would have to be made to get this to work in an environment with load balanced servers, multiple databases, etc. I have borrowed some of this from “Agile Web Development with Rails 4.”

Deployment server

Because it is outside the scope of this post, let’s assume you have installed the following on your deployment server:

At this point, install Ruby. We’ll assume it’s version 2.0:

rvm install ruby

Next, install Phusion Passenger (which is basically mod_ruby for Apache):

Then set up an empty git repository:

mkdir -p ~/git/my_app.git; cd ~/git/my_app.git; git init --bare

Finally, give your account permission to access the server as if it were remote, by adding a public key:

test -e ~/.ssh/id_dsa.pub || ssh-keygen -t dsa; cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

Development machine

On the development machine set up your Rails application with Capistrano:

echo "gem 'capistrano', '~> 3.0.0', group: :development" >> Gemfile

echo "gem 'rvm-capistrano', group: :development" >> Gemfile

bundle --binstubs; cap install

Put your application under version control if it is not already:

git init .

Commit the changes:

git add .; git commit -m "initial commit"

Next, push the changes to the deployment server:

git remote add origin ssh://user@host/~/git/my_app.git; git push origin master

Configure your Capistrano recipe, which I recommend basing on the example from the “Pragmatic Programmers” book. Also, edit the Capfile as necessary if you intend to use the Rails asset pipeline.

Finally, it’s time to deploy! Check your setup, and fix any warnings/errors:

cap deploy:setup

Once everything looks good, set up your database as needed with:

cap deploy:migrate

and

cap deploy:seed

Then deploy with:

cap deploy

This does the following:

  • checks out the latest commit
  • symlinks the assets (to preserve them between deploys)
  • uses Bundler to install any new gems or versions in Gemfile.lock
  • precompiles and adds cache busters to the assets
  • symlinks shared configuration files (that are not in version control, such as database.yml)
  • symlinks from the location known by Phusion Passenger
  • touches tmp/restart.txt to signal Phusion Passenger to restart the application

If anything goes wrong during these steps, Capistrano will emit a warning and roll back the deployment so no harm is done.