Deploy Your Ruby on Rails App Using Capistrano
Tags: ruby, rails
Published: 2022-07-27 11:46:24

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](https://capistranorb.com/documentation/plugins), many [plugins](https://capistranorb.com/documentation/third-party-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](https://capistranorb.com/documentation/getting-started/installation). 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:

```ruby
group :development do
  # Deployment
  gem "capistrano", "~> 3.10", require: false
  gem "capistrano-rails", "~> 1.3", require: false
end
```

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:

```shell
bundle install
```

Then you can install Capistrano:

```shell
bundle exec cap install
```

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.

```ruby
gem "capistrano-rvm"
```

Update your Capfile with the capistrano-rvm import:

```ruby
# Capfile
require 'capistrano/rvm'
```

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.

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

[Capistrano::RVM](https://github.com/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](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent).
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.

```ruby
# config/deploy/production.rb

server "11.22.333.444", user: "ubuntu", roles: %w{app db web}
```

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`.

```ruby
# config/deploy.rb

set :application, "ruby_rails_app"
set :repo_url, "git@github.com:username/ruby_rails_app.git"
```

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

You should also set up the [capistrano-secrets-yml](https://github.com/capistrano-plugins/capistrano-secrets-yml) gem.

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

```ruby
# Gemfile
gem "capistrano-secrets-yml"
```

Import it into Capfile:

```ruby
# Capfile
require "capistrano/secrets_yml"
```

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.

```ruby
# config/secrets.yml
production:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
```

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

```shell
$ rails secret
```

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:

```bash
# ~/.bashrc
export SECRET_KEY_BASE="YOUR_SECRET_KEY_BASE"
```

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

```shell
$ source ~/.bashrc
```

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:

```shell
$ cap production setup
```

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:

```ruby
# Capfile
require "capistrano/rails/migrations"
```

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

```ruby
# 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
```

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:

```shell
$ cap production deploy:check
```

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

```shell
$ cap production deploy
```

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

```shell
$ cap --tasks
```

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](https://appsignal.com/users/sign_up). 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.

```ruby
# config/appsignal.yml

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

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).

```shell
export APPSIGNAL_PUSH_API_KEY=XXX
```

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:

```shell
Notifying AppSignal of deploy with: revision: ee5e626fd31613ef068873f9cddb5f8c91538396, user: monteirobrena
AppSignal has been notified of this deploy!
```

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

![Applications list](https://blog.appsignal.com/images/blog/2022-07/applications-list.png)

And information about any deployments:

![Deployments list](https://blog.appsignal.com/images/blog/2022-07/deployments-list.png)

[Visit AppSignal's deployment documentation page](https://docs.appsignal.com/application/markers/deploy-markers.html) 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](https://blog.appsignal.com/ruby-magic)!**