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
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
Then you can install Capistrano:
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.
gem "capistrano-rvm"
Update your Capfile with the capistrano-rvm import:
# 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.
# config/deploy.rb
set :rvm_ruby_version, "ruby-2.6.3"
set :default_env, { rvm_bin_path: "~/.rvm/bin" }
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:
- Add the public key generated on your local machine to the
~/home/YOUR_USER/.ssh/authorized_keys
file. - 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.
- 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}
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"
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"
Import it into Capfile:
# 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.
# 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:
$ 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:
# ~/.bashrc
export SECRET_KEY_BASE="YOUR_SECRET_KEY_BASE"
Run the source to make it instantly available in your environment:
$ 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:
$ 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:
# 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:
# 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:
$ cap production deploy:check
If everything is ok with the configuration, you can start your deployment to production:
$ cap production deploy
In addition, you can check all available tasks in Capistrano with the command:
$ 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. 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` %>"
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
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!
You will now be able to see your application in AppSignal! 🎉
And information about any deployments:
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)
Great article @monteirobrena but Capistrano has issues with parallel SSH among others so you can also try & use Mina for faster deployments