Deploying Rails web application using Capistrano, Bundler and RVM

By Sagun Shrestha on Jun, 08, 2016

Developers today are moving fast towards docker image based deployments. However, there are still a few of us who like to stick to more mature workflow because of the nature of the work we do and the reliability we need to provide . For which, we are very careful about the tools we put into practice among our ranks. So, for those of you who fall among those few and are looking to deploy your first Rails application into a Virtual Private Server (VPS), this tutorial is for you.

Deploying your first Rails application can be confusing and may seem like a daunting task if you don't know what you are getting into. In this article, you will see how to do just that in simple steps using a deployment automation framework - "Capistrano". You will know just enough to have your first Rails app rolling in a VPS using Capistrano by the end of this tutorial.

What is Capistrano?

Capistrano is a framework built in ruby used to automate the deployment process.

Capistrano also includes support for assets pipeline and database migration especially for Ruby on Rails.

Capistrano uses SSH for deployment.

So, you should be able to ssh into the server from deployment system.

Enter following command to test this:

ssh username@servertodeploy.com

Installation

Step 1:

Add following in your Gemfile :

We are using Rails 4.2.6

gem 'capistrano', '3.5.0' gem 'capistrano-rails', '~> 1.1.6' gem 'capistrano-bundler', '~> 1.1.4' gem 'capistrano-rvm', '~> 0.1.2'

Step 2:

Enter the following command to install the gems:

bundle install

Step 3:

At this point “cap” command will be available. So, let us capify our project by executing following command:

Cap install

After running above command all the necessary file and folder structure for deployment will be generated.

Output on console will look something like this:

mkdir -p config/deploy

create config/deploy.rb

create config/deploy/staging.rb

create config/deploy/production.rb

mkdir -p lib/capistrano/tasks

create Capfile

Capified

Step 4:

By default following line are commented, so uncomment following lines in capfile:

require 'capistrano/rvm' require 'capistrano/bundler' require 'capistrano/rails/assets'

Configuration:

The configuration variable can be set in two ways:

Global

/config/deploy.rb

Stage specific

/config/deploy/production.rb

/config/deploy/staging.rb

We will be doing global configuration in this tutorial.

# deploy.rb # config valid only for current version of Capistrano lock '3.5.0' set :application, 'my_app_name' set :repo_url, 'git@example.com:me/my_repo.git' # RVM path selection: :rvm_type # :auto (default): just tries to find the correct path. ~/.rvm wins over /usr/local/rvm # :system: defines the RVM path to /usr/local/rvm # :user: defines the RVM path to ~/.rvm set :rvm_type, :system set :rvm_ruby_version, 'ruby-2.3.1' # Default branch is :master ask :branch, ‘master’ # Default deploy_to directory is /var/www/my_app_name set :deploy_to, '/var/www/my_app_name' # Default value for :scm is :git set :scm, :git # Default value for :format is :airbrussh. set :format, :pretty # You can configure the Airbrussh format using :format_options. # These are the defaults. # set :format_options, command_output: true, log_file: 'log/capistrano.log', color: :auto, truncate: :auto # Default value for :pty is false # set :pty, true # Default value for :linked_files is [ ] set :linked_files, fetch(:linked_files, [ ]).push('config/database.yml', 'config/secrets.yml') # Default value for linked_dirs is [ ] set :linked_dirs, fetch(:linked_dirs, [ ]).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'public/system') # Default value for default_env is { } # set :default_env, { path: "/opt/ruby/bin:$PATH" } # Default value for keep_releases is 5 set :keep_releases, 5

Now let us precompile our assets locally and upload file to our server. This will not only reduce the load in production server but also shorten the deployment time making us more efficient.

Create a new rake task file under /lib/capistrano/tasks/somefilename.rake

# somefilename.rake namespace :deploy do desc 'Restart application' task :restart do on roles(:all) do |host| # this will restart passenger server execute :touch, release_path.join('tmp/restart.txt') end end desc 'Precompile assets locally and then rsync to web servers' task :custom_compile_assets do # The command inside this block will run in our local machine run_locally do execute 'RAILS_ENV=production bundle exec rake assets:precompile' execute 'tar -zcvf assets.tar.tgz public/assets/' execute 'rm -rf public/assets' # This command will copy and transfer the assets.tar.tgz to username@servername.com:#{release_path}/ execute “scp assets.tar.tgz username@servername.com:#{release_path}/assets.tar.tgz" execute 'rm -rf assets.tar.tgz' end on roles(:all) do |host| # this command extracts assets.tar.tgz execute "cd #{release_path}; tar zxvf assets.tar.tgz" execute "cd #{release_path}; rm -rf assets.tar.tgz" end invoke 'deploy:restart' end end

Now, that our capistrano configuration is completed, let us deploy our application to serve by doing cap production deploy .

If your deploy is successful then check “/var/www/my_app_name” then your folder structure would look something as like:

My_app_name

current -> /var/www/my_app_name/release/<latest revision number>/

release xxxxxxxxxxxxxx xxxxxxxxxxxxxx xxxxxxxxxxxxxx

repo <VCS related data>

revisions.log

shared <linked_file and linked_dir>



Then you need to configure nginx for pointing the incoming request to the appropriate application in your server.

If your nginx configuration is ok then your rails application should be up and live in production.

Share This: