capistrano-rails: the two Rails tasks Capistrano v3 does not have
Official Ruby on Rails specific tasks for Capistrano
At a glance
- What is it?
- capistrano-rails is a small MIT licensed gem that adds Rails specific behaviour to Capistrano v3, chiefly cap deploy:migrate and cap deploy:compile_assets, plus the deployment options that decide which server runs your migrations and where your compiled assets land.
- Who is it for?
- capistrano-rails is the right fit for a Rails application that already deploys with Capistrano v3 and wants asset compilation and migrations wired into the same run, since the two tasks and the option set are maintained alongside the Capistrano releases they target.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 99 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A glue gem between Capistrano and a Rails app
The scope of this repository is narrow by design. It is not a deployment tool in its own right, it is the official set of Rails specific tasks for Capistrano, and the README states the surface area in two lines. Capistrano v3 knows how to put a release on a server and swap a symlink, but it knows nothing about Rails migrations or about the asset pipeline, so a Rails app on Capistrano would otherwise need custom tasks written for it. That is what this gem provides, with the two commands a Rails deploy actually needs, cap deploy:migrate and cap deploy:compile_assets. The audience is narrow too, anyone running a Rails application on Capistrano v3 who wants those two steps to behave like Rails expects rather than like a set of hand written shell commands.
The gem sits inside the Rails deploy, it does not replace it
The mechanism is ordinary Capistrano task composition, and it explains why the configuration surface is what it is. The gem exposes tasks that are namespaced under deploy, so they run as part of the normal deploy lifecycle rather than as separate commands you have to remember. The two tasks then delegate to the underlying frameworks. Migrations are delegated to the Rails task named by the migration_command option, which defaults to db:migrate, and asset compilation is delegated to the Rails assets task under the rails_assets_groups option, which defaults to the :assets group and is passed as the RAILS_GROUPS environment value for the assets:precompile task. Because the delegation goes through Rails tasks, a project with custom rake tasks can point the gem at them instead of the defaults, which is the point of exposing those two options rather than hard coding them.
Adding the gems and generating the configuration
Installation happens through the application's Gemfile, in the development group, with require set to false so that Bundler does not load the deployment tools in your application. The README gives the exact block:
group :development do
gem "capistrano", "~> 3.10", require: false
gem "capistrano-rails", "~> 1.6", require: false
endAfter the gems are declared you install them:
bundle installThen the generator creates the basic set of configuration files, which is the step that produces the Capfile and the deploy directory:
bundle exec cap installThe version constraints in that Gemfile block are worth noting rather than copying blindly. The capistrano constraint is ~> 3.10 and this gem is ~> 1.6, so the two are released on independent cycles and your Capistrano version has to be inside the range this gem was written against. The repository itself is small, with lib/ holding the implementation, alongside a gemspec, a Rakefile, a CHANGELOG.md, a Dangerfile and a .travis.yml file for continuous integration.
Requires belong in the Capfile, not in deploy.rb
There is one structural rule in the README that trips people up, and it comes with a reason. Requiring things inside config/deploy.rb does not work as intended, because the deploy file is evaluated later in the load order, after Capistrano has already decided which tasks exist. So the require has to live in the Capfile. The simple form pulls in everything, which the README describes as bundler, rails/assets and rails/migrations:
# Capfile
require 'capistrano/rails'If you want to be explicit instead, the three requires can be written by hand, and the comment on the first line is a fair summary of why bundler belongs there at all:
# Capfile
require 'capistrano/bundler' # Rails needs Bundler, right?
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'Choosing the explicit form means you decide which pieces of the gem load. Loading the whole thing is simpler, but it also means the assets and migrations tasks are present even in a stage that does not need them.
Every deploy.rb knob this gem reads
The options in config/deploy.rb are where the real decisions live, and the README lists them with their defaults. The migration side has four: rails_env, which sets the environment when it differs from the stage name, migration_role, which defaults to the :db role, migration_servers, which defaults to the primary :db server, and migration_command, which defaults to db:migrate. A fifth, conditionally_migrate, defaults to false and, when switched on, skips the migration if files in db/migrate were not modified. The asset side has its own set: assets_roles, defaulting to the :web and :app roles, assets_prefix, defaulting to assets, assets_manifests for the manifest files to look for, and rails_assets_groups for the RAILS_GROUPS value used by the assets:precompile task. Two of these have to agree with the Rails side of the application, since assets_prefix should match config.assets.prefix in your Rails config/application.rb and assets_manifests should match config.assets.manifest there too, which is the kind of cross-file agreement that fails late.
Migrations belong on the app role, not the db role
The README makes a recommendation that surprises people, and it argues it explicitly. Although migrations look like a concern of the database layer, Rails migrations are strictly related to the framework, so it recommends setting the role to :app instead of :db:
set :migration_role, :appThe stated advantage is that you will not need to deploy your application to your database server, which also gives a better separation of concerns. In practice that means the server running the migration needs a working checkout of the application and its dependencies, since the rake task runs inside the release, and the database host stays a database host. The trade-off is that if your app servers and database servers are separated by a network policy that blocks outbound connections, the migration now runs from the app side, so the path and the credentials have to work from there. The conditionally_migrate option interacts with this, since with it switched on a deploy with no changed files in db/migrate skips the step entirely.
Asset cleanup, symlinks and the master.key
Two smaller mechanisms are documented in their own sections. For asset cleanup, normalize_asset_timestamps lets you touch directories such as public/images, public/javascripts and public/stylesheets on each deploy, and keep_assets defaults to nil, which performs no cleanup, while setting it to a number keeps that many versions when you use Rails 4 or later. For symlinks, the README expects you to enable linked_dirs and linked_files so that shared directories such as log, tmp and public/uploads survive across releases, using the append helper, and it notes that before append existed in Capistrano 3.5 the same result came from fetch and push. The master.key handling is the one piece of real logic. This configuration uploads the file to the server when it is not already present:
append :linked_files, "config/master.key"
namespace :deploy do
namespace :check do
before :linked_files, :set_master_key do
on roles(:app) do
unless test("[ -f #{shared_path}/config/master.key ]")
upload! 'config/master.key', "#{shared_path}/config/master.key"
end
end
end
end
endThe check task runs before the linked files are processed, and it only uploads when the file is missing, so an already provisioned server is left alone. The README notes that the file is uploaded rather than symlinked, which is worth keeping in mind when you think about where the key lives on disk and who can read it there.
Version coupling and the state of the release line
The licence field on the repository says MIT, which is the permissive choice you want for a build tool that sits in the development group of an application. On maintenance, the facts are simple and slightly uneven. The last push was on 2026-07-16, the repository is not archived, and the most recent tags are v1.7.0 on 2024-12-30, v1.6.3 on 2023-07-04 and v1.6.2 on 2022-02-20. The changelog lives in the repository as CHANGELOG.md, so a version's contents are traceable without a release page. Two operational details round it out. The continuous integration configuration is a .travis.yml file, which is an older choice than the GitHub Actions workflows most projects use today, and the repository has a Dangerfile, the tool used to flag pull requests that need attention. For a gem whose job is to keep working against Capistrano and Rails, the practical upgrade cost is low, but the constraint to keep in mind is the version pairing, since the Gemfile block in the README asks for capistrano at ~> 3.10 and this gem at ~> 1.6, and a Capistrano upgrade outside that range means checking the changelog before the deploy pipeline breaks.
Editorial conclusion
capistrano-rails is the right fit for a Rails application that already deploys with Capistrano v3 and wants asset compilation and migrations wired into the same run, since the two tasks and the option set are maintained alongside the Capistrano releases they target. It is the wrong tool for a project that deploys through Rails' own tooling, for a Capistrano v2 setup, or for a team that wants migrations to run on the database server rather than the app server, which is the opposite of the recommendation in the README. Before you add it, check that the capistrano version your app pins falls inside the ~> 3.10 range the gemspec expects, put the require in Capfile rather than config/deploy.rb as the README insists, and confirm the assets_prefix value matches config.assets.prefix in your application.rb before the first deploy, since a mismatch fails only at asset compile time.
Frequently asked questions
Which Capistrano tasks does capistrano-rails add for a Rails app?
Two, according to the README: cap deploy:migrate and cap deploy:compile_assets. The migration task delegates to the Rails task named by the migration_command option, which defaults to db:migrate, and asset compilation uses the RAILS_GROUPS value set by the rails_assets_groups option.
How do I install capistrano-rails in a Rails application?
Add the capistrano and capistrano-rails gems to the development group of your Gemfile with require set to false, run bundle install, then run bundle exec cap install to generate the basic configuration files. The README's example pins capistrano at ~> 3.10 and capistrano-rails at ~> 1.6.
Should Rails migrations run on the db role or the app role in Capistrano?
The README recommends the app role, with set :migration_role, :app, because Rails migrations are strictly related to the framework. The stated advantage is that you do not need to deploy your application to your database server, which gives a better separation of concerns.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/capistrano-rails)Was this useful?