Using capistrano 3 for easy server configuration

I recently had the need to configure multiple rails apps on a new staging machine. Deploying and configuring applications can be really hard when you don’t have complete and working capistrano’s recipes.

I figured out that the best solution is having recipes that allow you to configure both the correct deploy of the application and the tuning of the application server, web server, delayed jobs, monitor application.

The advantages of this solutions is the fully control of your configuration which is stored in your repository instead of being scattered around in filesystem, in that way you can also view history of the tuning.

All you need to do is to integrate your recipes with templates generating configuration files customized for each environment.

Here’s an example of upstart configuration for puma web server using erb:

# lib/capistrano/templates/puma_upstart.erb
description "<%= fetch(:application) %> puma app"

start on filesystem or runlevel [2345]
stop on runlevel [!2345]

setuid <%= fetch(:user) %>
setgid <%= fetch(:user) %>

script
exec /bin/bash <<'EOT'
    source /home/<%= fetch(:user) %>/.rvm/scripts/rvm
    cd <%= current_path %>
    bundle exec puma -e <%= fetch(:rails_env) %> --config <%= fetch(:puma_config)%>
EOT
end script

Associated recipe to allow the template to run is:

# lib/capistrano/tasks/puma.cap
namespace :puma do

  desc "Setup Puma configuration and upstart script"
  task :setup do
    on roles(:app) do
      execute :mkdir, "-p #{shared_path}/config"

      # Upstart script for puma            
      template "puma_upstart.erb", "/tmp/puma_upstart", true
      execute :sudo ,:chmod, "+x /tmp/puma_upstart"
      execute :sudo, :mv, "/tmp/puma_upstart /etc/init/#{fetch(:app_env)}.conf"
    end
  end

end

def template(from, to, as_root = false)
  template_path = File.expand_path("../../templates/#{from}", __FILE__)
  template = ERB.new(File.new(template_path).read).result(binding)
  upload! StringIO.new(template), to

  execute :sudo, :chmod, "644 #{to}"
  execute :sudo, :chown, "root:root #{to}" if as_root == true
end

Your recipes can be organized in capistrano’s folder this way:

You can find a complete working example here. To make it work you’ll need these prerequisites:

Clone my repository and change config/deploy/staging.rb with your server parameter (remember that deployer user should be a sudoer). If everything is configured correclty you only have to create /var/apps on your server and set deploy user as owner, you’ll therefore be able to run cap staging deploy for your first deploy.

Run cap -vT to check the list of all possible tasks šŸ˜‰

Leave a Reply

Sort by:   newest | oldest | most voted
trackback

[…] Yes, we need templates, but we have ERB in Ruby, and googling a while we can find an easy solution for templating. […]

wpDiscuz