Deploy Rails with Capistrano 3

Share this article

CapistranoLogo

Capistrano is a remote server automation and deployment tool written in Ruby. It is an awesome tool which extends the rake (ruby make) DSL and can be used to deploy any web application.

In this article, I will be deploying a Rails application to an EC2 Ubuntu instance. You can follow along to deploy your application to any other PaaS platform, such as Digital Ocean, with ssh access.

I am using an Ubuntu instance for deployment and I’ll assume you already have a working application to be deployed remotely.

Step 1: Server Setup

First you need to create an EC2 instance from the Amazon AWS console, ssh into the instance, and install the necessary packages (database, webserver, etc.) to run your web application. You will have to update the firewall settings on EC2 and on Google App Engine, otherwise your application won’t be accessible from outside world. Another thing is to point your domain to the instance you have created using the DNS tools provided by your domain registrar

I am not going to provide step by step instructions to setup your server. You may use this server setup script to setup your server for deploying a Rails application.

$ ssh -i <path-to-pem-file> ubuntu@<ec2-instance-address>
$ wget "https://gist.githubusercontent.com/42races/8d2c597d10dc9a0bddb0/raw/cbc4373b27dc09d2fc88a660ef1ad1b4c246c0e4/server_setup.sh"
$ chmod +x server_setup.sh
$ ./server_setup.sh

This script will install the necessary packages, creates a deploy user who manages our Rails application, downloads and installs RVM and Ruby, and add your ssh public key to the instance’s authorized keys.

I am using nginx for this application with the following configuration. Put your configuration in a file (eg: foobar.conf) and copy it to the /etc/nginx/sites-available directory. I am going to use “foobar” as my application name and “foobar.com” as my application domain address.

upstream foobar {
  # uncomment the following line if multiple application servers are used.
  # this will force nginx to send requests from the same client to the same
  # application server.
  # ip_hash;
  server unix:///home/deploy/apps/foobar/shared/tmp/sockets/puma.sock fail_timeout=0;
}

server {
  listen 80 default deferred;
  server_name foobar.com;
  root /home/deploy/apps/foobar/current/public;

  location ^~ /assets/ {
    # gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  try_files $uri/index.html $uri @foobar;
  location @foobar {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://foobar;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 10;
}

Step 2: Install Capistrano

Go to your Rails application and add the following line in the Gemfile

group :developemnt do
  gem 'capistrano', '~> 3.1.0'
end

Run the bundle command in the application directory to intall the gem.

$ bundle

check the version of the installed capistrano as follows

$ bundle exec cap -V

Capistrano Version: 3.1.0 (Rake Version: 10.2.2) ###

Capistrano comes with a set of default tasks that you can list using the following command.

$ bundle exec cap -vT

Step 3: Initialize Capistrano

Run the following command to initialize capistrano.

$ bundle exec cap install

The above command creates few files in your application directory.

Capfile
config/deploy.rb
config/deploy/production.rb
config/deploy/staging.rb
lib/capistrano/tasks          # directory

As you can see, it generated a different configuration file for production and staging environments. Since version 3, capistrano is multistaged by default. There is a global configuration file called config/deploy.rb where you can put the configuration commnon to all the environments.

Step 4: Edit Capfile

Open the Capfile in your favourite editor and add/uncomment the following lines

require 'capistrano/setup'
require 'capistrano/deploy'

Capistrano has been re-architectured to be use plugins. In our case, we can use the bundler, rvm, and rails plugins. Plugins are packaged as gems, so we can add them to the Gemfile and require it in the Capfile. Here is the list of official plugins.

We need an application server to run our application, and I am going to use puma.

Add this to the Gemfile:

group :development do
  gem 'capistrano', '~> 3.1.0'
  # cap tasks to manage puma application server
  gem 'capistrano-puma', require: false
  gem 'capistrano-rails',   '~> 1.1', require: false
  gem 'capistrano-bundler', '~> 1.1', require: false
  gem 'capistrano-rvm',   '~> 0.1', require: false
end

And bundle to install these gems. In the Capfile, add the following lines:

require 'capistrano/rvm'
require 'capistrano/bundler'
require 'capistrano/puma'
require 'capistrano/rails/assets' # for asset handling add
require 'capistrano/rails/migrations' # for running migrations

Step 5: Global Configuration

Now open config/deploy.rb in your favourite editor to set various options, like application name:

set :application, 'foobar'                       # application name
set :repo_url, 'git@example.com:me/foobar.git'   # your repo url
set :deploy_to, '/home/deploy/apps/foobar'

Set the version control you are using:

set :scm, :git

The branch you want to deploy:

set :branch, 'master'

Number copies of the release you want to keep

set :keep_releases, 5

It’s possible to prompt the user for answers to some of these questions. For example, if you want to dynamically set the git branch name, do this:

ask :branch, proc { `git rev-parse --abbrev-ref HEAD`.chomp }

Some other options to format the output are:

set :format, :pretty
set :log_level, :debug
set :pty, true

It’s wise to setup the linked directories to avoid overwriting them on each deploy:

set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

Step 6: Environment Configuration

Open the file corresponding to the chosen deployment environment. So, if we are deploying to production open the config/deploy/production.rb file and set the configuration options. If the environment file is not available simply create the file.

set :stage, :production

role :app, %w{deploy@<vps_ip_address>}
role :web, %w{deploy@<vps_ip_address>}
role :db,  %w{deploy@<vps_ip_address>}

Step 8: Puma Settings

Some plugins require their own configuation, and Puma is one of them. Add the following lines to the config/deploy.rb

set :puma_rackup, -> { File.join(current_path, 'config.ru') }
set :puma_state, "#{shared_path}/tmp/pids/puma.state"
set :puma_pid, "#{shared_path}/tmp/pids/puma.pid"
set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock"
set :puma_conf, "#{shared_path}/puma.rb"
set :puma_access_log, "#{shared_path}/log/puma_error.log"
set :puma_error_log, "#{shared_path}/log/puma_access.log"
set :puma_role, :app
set :puma_env, fetch(:rack_env, fetch(:rails_env, 'production'))
set :puma_threads, [0, 16]
set :puma_workers, 0
set :puma_init_active_record, true
set :puma_preload_app, true

Step 8: Deploy

To deploy your application, just run the deploy task:

$ bundle exec cap production deploy

Note that you have to specify the environment in every cap command.

Once deployment completes, visit “foobar.com” (or whatever you called it) in your browser.

Upgrading to Capistrano 3

Upgrading a Rails application to use capistrano 3 is very easy. The first step is to backup your old capistrano configuration files:

Capfile
config/deploy.rb

If you have multiple stages for your application, backup them also.

Now remove the old capistrano gem from Gemfile along with any related plugins. At this point, simply follow the previously mentioned steps in this article. Easy.

I hope this post helps you get onto Capistrano 3.

Frequently Asked Questions (FAQs) about Deploying Rails with Capistrano 3

What are the prerequisites for deploying Rails with Capistrano 3?

Before you can deploy Rails with Capistrano 3, you need to have a few things set up. First, you need to have Ruby on Rails installed on your local machine. You also need to have a Git repository for your Rails application. Additionally, you need to have SSH access to the server where you want to deploy your application. Lastly, you need to have Capistrano 3 installed. You can install it by adding the gem ‘capistrano’, ‘~> 3.11’, require: false to your Gemfile and running bundle install.

How do I configure Capistrano for my Rails application?

Configuring Capistrano for your Rails application involves creating a Capfile and deploy.rb file in your application’s config directory. The Capfile specifies the tasks that Capistrano should perform during deployment, while the deploy.rb file contains the configuration settings for your deployment, such as the repository URL, deployment directory, and server details.

How do I deploy my Rails application using Capistrano?

To deploy your Rails application using Capistrano, you need to run the cap production deploy command in your terminal. This command tells Capistrano to deploy your application to the production environment. Before running this command, make sure you have properly configured your Capfile and deploy.rb file.

What are the common issues encountered when deploying Rails with Capistrano and how can I troubleshoot them?

Some common issues when deploying Rails with Capistrano include SSH connection problems, Git clone errors, and bundle install failures. To troubleshoot these issues, you can check the Capistrano output for any error messages. You can also use the cap production deploy:check command to check if your server is properly set up for deployment.

Can I automate the deployment process with Capistrano?

Yes, Capistrano is designed to automate the deployment process. You can define tasks in your Capfile that Capistrano will automatically execute during deployment. For example, you can automate tasks such as pulling the latest code from your repository, running bundle install, precompiling assets, and restarting your application server.

How can I rollback a deployment with Capistrano?

If something goes wrong during deployment, Capistrano allows you to rollback to the previous release. You can do this by running the cap production deploy:rollback command. This command will undo the last deployment and revert your application to the previous state.

How can I customize the deployment process with Capistrano?

Capistrano is highly customizable. You can define your own tasks in the Capfile and specify when they should be run during the deployment process. You can also customize the deploy.rb file to suit your specific deployment needs.

Can I use Capistrano to deploy to multiple servers?

Yes, Capistrano supports multi-server deployment. You can specify multiple servers in your deploy.rb file and Capistrano will deploy your application to all of them simultaneously.

How can I update my Ruby gems during deployment with Capistrano?

You can update your Ruby gems during deployment by adding a task in your Capfile to run bundle install. This will ensure that all your gems are up-to-date when your application is deployed.

Can I use Capistrano with other version control systems besides Git?

Yes, while Capistrano is often used with Git, it also supports other version control systems like Mercurial and Subversion. You just need to specify the repository URL and SCM in your deploy.rb file.

Deepak KumarDeepak Kumar
View Author

Web engineer from Kerala, India. Rubyist, Javascripter, gopher, Blogger and loves Startups. Now works with http://theamazingfactory.com.

Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week