This week I 'capified' a Rails application I've been developing.  It's a basic Rails 4 app using Git for version control and is deployed across multiple environments: development-integration, test-integration, and production.  Along with Capistrano's documentation, there are quite a few Capistrano 3 setup/configuration tutorials on the web that are very helpful to get basic deployments working across multiple environments.

Basic Capistrano setup steps consist of:

  • Update Gemfile to include capistrano gems:
gem 'capistrano', '~> 3.1'
gem 'capistrano-rails', '~> 1.1'
  • Run Capistrano install task:
bundle exec cap install
  • Configure Capfile to require what you need (asset precompilation, migrations, etc):
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
  • Configure environment specific information in the deploy/<env>.rb files.

So far so good, right?  Now I want to throw a wrench in the spokes.  I don't want to precompile assets in the development-integration environment, but I would like to precompile assets in the other environments.  Why?  Well, the application is very javascript heavy.  It's useful to be able to use browser tools, such as firebug, to set breakpoints in un-minified, uncompressed code in an integration environment.  (Yes, I'm aware that some bugs manifest themselves due to precompiling assets and this wouldn't solve that problem.)

Unfortunately, Capistrano doesn't provide a simple environment flag to turn on/off precompiling assets per environment.  Out of the box, it's all or nothing.  However, you can clear the existing 'assets_precompile' task provided by capistrano and then re-define this task in deploy.rb.

# deploy.rb

namespace :deploy do
  desc 'Compile assets'
  task :compile_assets => [:set_rails_env] do
    unless fetch(:rails_env) == 'development-integration'
      invoke 'deploy:assets:precompile'
      invoke 'deploy:assets:backup_manifest'

Thankfully the provided 'compile_assets' task is only ~4 lines of code making it easy to re-define. The conditional statement above is just a simple example of how to check the rails environment.  This could also be accomplished via a custom flag set in each of the deploy/<env>.rb files and checking that custom flag in your custom 'compile_assets' task.