Ruby on Rails: Using Capistrano to deploy application and run custom task

What is Capistrano?

How to use it?

group :development do
gem "capistrano", "~> 3.10", require: false
gem "capistrano-rails", "~> 1.6", require: false
bundle install
bundle exec cap install
| |
| |--deploy.rb
| |
| |--deploy/
| |
| |--production.rb
| |--staging.rb

Getting start

  • modify Capfile
require 'capistrano/setup'# Include default deployment tasks
require 'capistrano/deploy'
require 'capistrano/scm/git'
install_plugin Capistrano::SCM::Git
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano/puma'
install_plugin Capistrano::Puma
install_plugin Capistrano::Puma::Workers
require 'capistrano/sidekiq'
# Load custom tasks from `lib/capistrano/tasks` if you have any defined
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }
  • modify config/deploy.rb
set :application, 'my_app'      # my_app is your project name
set :repo_url, '<repo url>' # your project remote repository url
# it could be github project url
ask :branch, :master # Default deploy branch is :master
set :deploy_to, '/home/my_app' # deploy project to /home/my_app
  • modify config/deploy/staging.rb or config/deploy/production.rb and set the IP address or the domain name of the machine where your code will be deployed, the role of the machine. Capistrano uses a concept of a role to control over which tasks are run on which servers. For example, you may want to apply a task only to a database server and skip it when deploying to a web server. The role acts as a filter that tells Capistrano to group tasks with the same role together before executing them on a server matching a specific role.
server '', user: 'deployer', roles: %w[db web]
server '', user: 'deployer', roles: %w[app]
set :default_env, path: '/usr/local/ruby-2.5.3/bin:$PATH'set :puma_workers, 2
set :sidekiq_processes, 2
  • Start deployment by use capistrano command line. After finishing the modification of above configuration, we finally could start deployment. Here are some command line would be use to start the deployment. Usually we would use bundle exec cap 'environment' deploy to deploy our project to specific stage environment.
# list all available tasks
$ bundle exec cap -T

# deploy to the staging environment
$ bundle exec cap staging deploy

# deploy to the production environment
$ bundle exec cap production deploy
├── current -> /home/my_app_name/releases/20210511115200/
├── releases
│ ├── 20210509115200
│ └── 20210511115200
├── repo
│ └── <VCS related data>
├── revisions.log
└── shared
└── <linked_files and linked_dirs>

Use custom role and run custom task

namespace :greetings do
on roles(:app) do
execute "echo Hello Word"
after :deploy, 'greetings:hello'
before :deploy, 'greetings:hello'
server '', user: 'deployer', roles: %w[db web]
server '', user: 'deployer', roles: %w[app]
server '', user: 'deployer', roles: %w[sidekiq_server]
set :default_env, path: '/usr/local/ruby-2.5.3/bin:$PATH'set :puma_workers, 2
set :sidekiq_processes, 2
namespace :sidekiq_server do
task :start do
on roles(:sidekiq_server) do
within current_path do
execute :bundle, "exec sidekiq --environment staging --logfile /home/my_app/shared/log/sidekiq.log --daemon"
after :deploy, 'sidekiq_server:start'




Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store



Programming Skill learner and Sharer | Ruby on Rails | Golang | Vue.js | Web Map API