Part 1: Setup Capistrano

(1) Add Capistrano gem and related task gems to your Gemfile. Typical a minimum requirement would look like this:

gem 'capistrano'
gem 'capistrano-bundler'
gem 'capistrano-rails'

(2) If your server runs on Phusion Passenger, you can add:

gem 'capistrano-passenger'

(3) If you install Ruby via rbenv or rvm on your server, you can add either one of the following:

gem 'capistrano-rbenv'
gem 'capistrano-rvm'

(4) If you are using delayed job, you can add:

gem 'capistrano3-delayed-job'

(5) Above are common Capistrano task gems, you can add more as and if needed. Next, we install the gems.

bundle install

(6) Install Capistrano files with this command:

cap install

(7) This creates several files including:

  • Capfile
  • config/deploy.rb
  • config/deploy/production.rb
  • config/deploy/staging.rb

(8) Edit 'Capfile' to enable modules that you need. Example:

require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails'
require 'capistrano/passenger'
require 'capistrano/delayed_job'

(9) If you are working on an API project that does not involve assets. You will probably want to break down 'capistrano/rails' and require only migrations.

# require "capistrano/rails/assets"
require "capistrano/rails/migrations"

(10) Edit 'deploy.rb' to add configurations for each module. Common config to set:

# config valid for current version and patch releases of Capistrano
lock "~> 3.10.0"

# What is your app name?
set :application, 'myapp'

# Where is your Git repository?
set :repo_url, 'git@git.git'

# Which directory to execute the deployment?
set :deploy_to, '/path/to/myapp'

# These files are copied (symlink) after each deployment
append :linked_files, "config/database.yml", "config/secrets.yml", "config/secrets.yml.key", "config/custom_configs.yml"

# These directories are shared across deployment.
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets"

# How many releases to keep?
set :keep_releases, 10

# rbenv ruby version
set :rbenv_ruby, '2.4.2'

# How many copies of assets to keep?
set :keep_assets, 2

# How many workers to start
set :delayed_job_workers, 2

(11) Setup each environment under the deploy directory. For example, production.rb.

server 'myserver1.com', user: 'ubuntu', roles: %w[app db web]
server 'myserver2.com', user: 'ubuntu', roles: %w[app db web]

Part 2: Setup Server

(1) SSH to your server.

(2) Create your "deploy_to" directory.

mkdir /path/to/myapp

(3) Create a "shared" directory under your "deploy_to" path.

mkdir /path/to/myapp/shared

(4) Create and store a copy of each "linked_files" in respective directory. E.g.

  • shared/config/database.yml
  • shared/config/secrets.yml.key
  • shared/config/custom_configs.yml

(5) Point your HTTP server application path to "deploy_to/current/public" directory. For example, in Nginx:

root /path/to/myapp/current/public;

(6) Make sure that correct Ruby version is installed and bundler gem is installed.

(7) Make sure that the database specified in the config file is created.

Part 3: Deploy

(1) Provided that your deployment machine has appropriate SSH key configured. Deployment is just a simple command:

cap <environment> deploy

Where <environment> depends on your available environment. E.g. production, staging, etc.

(2) When deployment is successful, a log will be written to revisions.log in your "deploy_to" directory.