DEV Community

Cover image for Deploy Your Ruby on Rails App Using Capistrano
Brena Monteiro for AppSignal

Posted on • Originally published at blog.appsignal.com

Deploy Your Ruby on Rails App Using Capistrano

In this article, we will configure Capistrano in a Ruby on Rails application. We will then deploy the app to a cloud instance that runs Ubuntu as an operating system, independent of your hosting provider. You can use any cloud service, or even an on-premises server, to test or replicate the steps we'll take.

Once we've deployed the app, we'll look briefly at how you can monitor your app's deployments using AppSignal.

But first, you might ask: why should I use Capistrano in the first place?

Why Choose Capistrano for Your Ruby on Rails App?

You might be wondering if it still makes sense to continue using Capistrano for deployment these days. We now have many tools and services available for deployments and continuous integration.

But to answer that, we need to revisit the origin of Capistrano and its evolution to the present day. The first tag created in the Capistrano repository was in 2006. Its objective was to allow the execution of commands remotely via SSH in parallel on several machines, all using DSL. Since then, Capistrano has evolved, by adding several features to each version.

Currently at version 3 after 16 years, Capistrano continues to be actively developed and is now known as a framework for building automated deployment scripts.

So it's no longer just a tool to run commands on remote machines. In addition to Capistrano's features, many plugins and other gems specifically run with Capistrano.

Because of this and the fact that a large community still uses Capistrano, it remains a great tool for automated deployment.

Adding Capistrano to Your Ruby on Rails App

First, you'll need to configure a Ruby on Rails application to integrate it with Capistrano. You can follow Capistrano's documentation. However, it has more information than you'll need for the scope of this post. So for simplicity's sake, this article only includes the necessary steps and configuration that you will need.

To start the configuration, add the Capistrano gem in the development section of your Gemfile:

group :development do
  # Deployment
  gem "capistrano", "~> 3.10", require: false
  gem "capistrano-rails", "~> 1.3", require: false
end
Enter fullscreen mode Exit fullscreen mode

You need the capistrano-rails gem to run a migration on your database and handle the assets that we will see in the next sections.

Now run bundle install to add Capistrano to your application:

bundle install
Enter fullscreen mode Exit fullscreen mode

Then you can install Capistrano:

bundle exec cap install
Enter fullscreen mode Exit fullscreen mode

This command will create a file called Capfile that imports and configures the required libraries. Furthermore, a file called deploy.rb (created inside the config folder) will contain all the configurations that should be included in a deployment with Capistrano.

Note: Capistrano creates a file to override the deploy.rb configuration for both the staging and production environments, but that will not be covered in this article.

With that, you're ready to start configuring and communicating between your Ruby on Rails application and the server.

Server Configuration with Capistrano for Your Rails App

In this step, we'll add instructions to the Capistrano configuration file. The instructions will communicate to your server on where your app will be deployed. This is where we'll define access information and the security configuration.

To ensure that your production environment runs the same version of Ruby as the version you use in development, use a Ruby version manager, such as RVM or rbenv (Capistrano supports both).

In this article, we'll use RVM. Make sure you have RVM installed on your development machine and production server. Also, check if your version of Ruby is the same in your environments and project.

Adding capistrano-rvm Gem

The Capistrano project provides a gem called capistrano-gem that lets you easily configure RVM. To include it in your project, add it to your Gemfile within your development group, and run bundle install again.

gem "capistrano-rvm"
Enter fullscreen mode Exit fullscreen mode

Update your Capfile with the capistrano-rvm import:

# Capfile
require 'capistrano/rvm'
Enter fullscreen mode Exit fullscreen mode

In the deploy file, add a configuration to set the Ruby version and the path to RVM (especially if you used a different path to install RVM).

If no version of Ruby is defined, Capistrano chooses the latest version that you have installed on the server where your application will be deployed.

# config/deploy.rb
set :rvm_ruby_version, "ruby-2.6.3"
set :default_env, { rvm_bin_path: "~/.rvm/bin" }
Enter fullscreen mode Exit fullscreen mode

Capistrano::RVM has other settings for RVM, but the ones shown here are what you'll need to get started.

Set Up Your Server Configuration

It is good practice to define a user for the deployment. Don't forget to follow these steps on your server before you start a deployment:

  1. Add the public key generated on your local machine to the ~/home/YOUR_USER/.ssh/authorized_keys file.
  2. Create a key and include the public key in the code repository. This gives you access to clone your project within the production server. If you are using GitHub, you can follow this documentation.
  3. Set permissions to write to the /var/www/ directory.

You can configure Capistrano for any environment you need. You just need to create a new configuration file inside config/deploy/<environment_name>.rb, then configure the IP or DNS, and username, to connect to your server.

# config/deploy/production.rb

server "11.22.333.444", user: "ubuntu", roles: %w{app db web}
Enter fullscreen mode Exit fullscreen mode

To complete the deployment setup, include information about your application, such as the application name and code repository URL. Any information which is the same for all environments must be added to config/deploy.rb. Keep specific environment configurations in config/deploy/<environment_name>.rb.

# config/deploy.rb

set :application, "ruby_rails_app"
set :repo_url, "git@github.com:username/ruby_rails_app.git"
Enter fullscreen mode Exit fullscreen mode

Set Up capistrano-secrets-yml Gem for Your Rails App

You should also set up the capistrano-secrets-yml gem.

Add the gem to your Gemfile and run the bundle to install:

# Gemfile
gem "capistrano-secrets-yml"
Enter fullscreen mode Exit fullscreen mode

Import it into Capfile:

# Capfile
require "capistrano/secrets_yml"
Enter fullscreen mode Exit fullscreen mode

Then create config/secret.yml in your application and include the secret key base as an environment variable. This variable will be created on your production server. Remember not to commit this file to your repository.

# config/secrets.yml
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
Enter fullscreen mode Exit fullscreen mode

Inside your application folder in the terminal, run this command to generate the secret key base:

$ rails secret
Enter fullscreen mode Exit fullscreen mode

Copy the generated key and use it to set your SECRET_KEY_BASE on the production server. Access your production server and export the SECRET_KEY_BASE variable in the final ~/.bashrc file, so it is always available:

# ~/.bashrc
export SECRET_KEY_BASE="YOUR_SECRET_KEY_BASE"
Enter fullscreen mode Exit fullscreen mode

Run the source to make it instantly available in your environment:

$ source ~/.bashrc
Enter fullscreen mode Exit fullscreen mode

Now, back on your machine, access the application folder in the terminal and run the Capistrano command below to create config/secrets.yml on the production server:

$ cap production setup
Enter fullscreen mode Exit fullscreen mode

All done! Now it's time to configure Capistrano to run a migration.

Configure Capistrano to Perform a Database Migration

Now it's time to configure Capistrano to run database-related commands.

The capistrano-rails gem already included in your Gemfile can be configured to perform a migration on each deployment. We just need to import it into Capfile:

# Capfile
require "capistrano/rails/migrations"
Enter fullscreen mode Exit fullscreen mode

But if you want to run the seeds on deployment, you need to create a new task to run after the migration:

# config/deploy.rb

namespace :deploy do
  desc "Run seed"
  task :seed do
    on roles(:all) do
      within current_path do
        execute :bundle, :exec, 'rails', 'db:seed', 'RAILS_ENV=production'
      end
    end
  end

  after :migrating, :seed
end
Enter fullscreen mode Exit fullscreen mode

With that, your app is finally ready to be deployed!

Start Deployment of Your Ruby on Rails App

Let's see how to perform a deployment from our local machine by directly updating our server to the new version of our application.

When you execute a deployment command, Capistrano will connect to your server. From there, Capistrano will try to clone the code from the repository defined in the configuration file (config/deploy.rb). Then other tasks will be performed, following the deployment flow.

Capistrano's deploy:check command validates that the Git configuration is alright and that Capistrano has correct access to the directories that will be used in the deployment.

To use it, pass the environment. In this case, we are using production:

$ cap production deploy:check
Enter fullscreen mode Exit fullscreen mode

If everything is ok with the configuration, you can start your deployment to production:

$ cap production deploy
Enter fullscreen mode Exit fullscreen mode

In addition, you can check all available tasks in Capistrano with the command:

$ cap --tasks
Enter fullscreen mode Exit fullscreen mode

Now, in our final step, let's integrate our Ruby on Rails application with AppSignal and start monitoring it.

How to Integrate AppSignal with Capistrano and Your Rails App

AppSignal is a monitoring tool, so you might wonder why it's included in this article. That is a valid question, as monitoring is not directly related to deployments.

That said, AppSignal is a valuable tool when it comes to monitoring your Ruby on Rails application and keeping track of deployments in each environment. So let's see how we can set up AppSignal for your app.

You will need an AppSignal account, which you can create on AppSignal's sign-up page. Pick Ruby as your language and follow the steps to install AppSignal in your application.

Once installed, a file will be created to configure AppSignal. What's important here is to define the revision — information that will be checked after deployment to see if a new version of an application has been deployed. In this case, we will use the Git log as revision information to ensure that each new code deployment will notify AppSignal.

# config/appsignal.yml

production:
  <<: *defaults
  active: true
  revision: "<%= `git log --pretty=format:'%h' -n 1` %>"
Enter fullscreen mode Exit fullscreen mode

It is also good practice to export AppSignal environment variables to your production server (especially the API key, so as not to keep it in the AppSignal configuration file).

export APPSIGNAL_PUSH_API_KEY=XXX
Enter fullscreen mode Exit fullscreen mode

And now we can rerun the deployment. If everything is set up correctly, you will see a message like this at the end of the deployment:

Notifying AppSignal of deploy with: revision: ee5e626fd31613ef068873f9cddb5f8c91538396, user: monteirobrena
AppSignal has been notified of this deploy!
Enter fullscreen mode Exit fullscreen mode

You will now be able to see your application in AppSignal! 🎉

Applications list

And information about any deployments:

Deployments list

Visit AppSignal's deployment documentation page to learn more about deployment integration and other features available for Ruby on Rails applications.

Wrap Up and Next Steps

In this post, we explored how to use Capistrano to deploy your Ruby on Rails app. We first added Capistrano to an app, then configured and deployed it, before finally setting up monitoring with AppSignal.

If you'd like to explore further, you can configure Capistrano to run from an integration connected to your repository's pipeline. Tools like Bitbucket, GitHub, and GitLab provide settings to manage this process and can be used in conjunction with Capistrano.

Happy coding!

P.S. If you'd like to read Ruby Magic posts as soon as they get off the press, subscribe to our Ruby Magic newsletter and never miss a single post!

Top comments (1)

Collapse
 
vinayhegde1990 profile image
Vinay Hegde

Great article @monteirobrena but Capistrano has issues with parallel SSH among others so you can also try & use Mina for faster deployments