You are currently viewing Remote Server Automation and Deployment with Capistrano

Remote Server Automation and Deployment with Capistrano

  • Post published:July 22, 2016

Capistrano is a tool used for remote server automation and deployment, written in Ruby. It uses SSH to connect with server for performing various operations and Rake to define tasks required to perform deployment on a specific server. To automate repetitive deployment tasks, it can also be used for any language or framework including Java, PHP, Rails, etc.

Additionally, you can write your own automated deployment scripts by writing rake tasks. However, Capistrano provides a basic structure for multiple plugins to deploy them easily. Following is it’s file structure:

├── Capfile
├── config
│   ├── deploy
│   │   ├── production.rb
│   │   └── staging.rb
│   └── deploy.rb
└── lib
    └── capistrano
            └── tasks

Here, Capfile is used to require plugin files and define user defined rake tasks. Config/Deploy is a directory where environment (staging/production) specific files are placed for the server. Deploy.rb file is used to define generic variables, configurations, and tasks, etc. Additionally, Lib/Capistrano/Tasks is a directory where user defined custom rake tasks for capistrano are placed.

Setup in Ruby on Rails

In a project’s Gemfile, specify “capistrano” as a core gem and any other gem like “capistrano-rails” to provide extended core functionality.

group :development do
  gem "capistrano", "~> 3.4" #capistrano core library
  gem 'capistrano-rails', '~> 1.1' #capistrano plugin for rails specific features

To add extra functionality in Capfile, “capistrano-rails” gem is required here. Add the following line of code to import the required gem:

require 'capistrano/rails'

To create capistrano recipe in deploy.rb file, set the following variables used by capistrano for all environments:

set :application, application/folder_name/on/server
set :branch, 'master' #your SCM branch
set :scm, :git
set :rails_env, :production
set :pty, true
set :keep_releases, 5

To create capistrano recipe in config/deploy/production.rb file, set environment specific variables (production in the following case):

server ‘serverIP_or_domain’, user: ‘user_name_to_connect_to_server’, roles: %w{app db web}
set :repo_url, 'Your git or any other SCM's repository url'
set :deploy_to, "/home/ubuntu/#{fetch :application}"

Here, “serverIP_or_domain” is the IP address or domain name that the client machine uses to connect with server and for its deployment.

Tasks that are shared among all environments are placed in deploy.rb file like variables while environment specific tasks are placed in their respective environment files (for example, tasks of production environment will be placed in config/deploy/production.rb file).

The following two tasks are presented as an example of rake tasks having Capistrano DSL support.

  1. This example is used for checking the access to a specified server.
    desc "Check that we can access specified server"
    task :check_write_permissions do
      on roles(:all) do |host|
        if test("[ -w #{fetch(:deploy_to)} ]")
          info "#{fetch(:deploy_to)} is writable on #{host}"
          error "#{fetch(:deploy_to)} is not writable on #{host}"
  2. The example is used for checking whether Git local branch is synced with remote branch or not.
    desc "checks whether local git is in sync with remote"
    task :check_is_repo_updated do
      on roles(:web) do |host|
       unless `git rev-parse HEAD` === `git rev-parse origin/#{fetch(:branch, 'master')}`
          info "WARNING: local git is not synced with #{fetch(:branch, 'master')}"
          info "To solve this: Run git push origin #{fetch(:branch, 'master')} to sync"
    # make sure that check_is_repo_updated runs after check_write_permissions task
    after :check_write_permissions, :check_is_repo_updated