Serj L aka Loremaster

Blog of Rails developer.

Enlarge Your Capistrano

| Comments

I would like to tell you about few gems, which would make your deployment life a little bit easier. Well, it worked for me.

rvm-capistrano

Our first hero on the scene is rvm-capistrano. This hero is special, he prefers only capistrano №2. But time is changing and capistrano №3 is walking on streets of our computers, so, if you have seen it and even use it then you may select another hero: rvm1-capistrano3.

But I will talk about oldies here. What does this gem actually do? It brings integration between Rvm and capistrano. There are some discusses in the internet what to use, some people prefer rbenv, other use Rvm. Actually, rbenv is very small and it has very small code base, but it doesn’t have power of Rvm, so your choice should depend on your situation. But let me talk about hero, he is waiting to be presented!

Installation is simple, because you already use capistrano, do you?

Gemfile
1
2
3
4
group :development do
  gem 'capistrano'
  gem 'rvm-capistrano'
end

Now you should call the hero, to do that just place this line somewhere in the top of your capistrano’s deploy file:

config/deploy.rb
1
require 'rvm/capistrano'

This will bring to you few things. First of all, it extends base to automatically set :default_shell. Also it adds these tasks:

  • rvm:info – show rvm info
  • rvm:list – list rvm rubies
  • rvm:info_list – show info and list rubies
  • rvm:install_rvm – install RVM of the given choice to the server.
  • rvm:install_ruby – install RVM ruby to the server, create gemset if needed
  • rvm:create_gemset – create gemset

If you forget about correct syntax you can always run cap -T rvm to list all tasks which gem provides. There are some additional tasks which you may include you can check them out in readme.

With this gem you may, for example, update Rvm on each deploy and make sure that ruby is installed:

config/deploy.rb
1
2
3
4
5
6
require "rvm/capistrano"

set :rvm_ruby_string, :local        # use the same ruby as used locally for deployment

before 'deploy', 'rvm:install_rvm'  # install/update RVM
before 'deploy', 'rvm:install_ruby' # install Ruby and create gemset (both if missing)

Or set default ruby version and gemset:

config/deploy.rb
1
set :rvm_ruby_string, '2.0.0@gemset_name'

Or even restrict Rvm on some servers!

config/deploy.rb
1
2
3
4
set :rvm_require_role, :rvm
require "rvm/capistrano/selector_mixed"
role :rvm, "web1", "web2"
role :app, "web1", "web2", "web3"

Check out readme for more details about this hero.

capistrano-notifier

If you use heroku then you receive email when deploy finishes. A like this feature and it is very cool that you can have the same functionality with capistrano. So, meet the second hero: capistrano-notifier.

The superpower of this hero is sending email with commits, which has been deployed, for example:

1
2
3
4
5
6
7
8
9
10
Obi-Wan Kenobi deployed
Power branch
stage to
staging on
02/24/2014 at
02:37 PM MSK

https://github.com/jedis/stage/compare/8fc335c...e3a999c
8e8b39c The force is strong with this one (Obi-Wan Kenobi)
b17e255 New lightsaber (Obi-Wan Kenobi)

Looks pretty cool, huh? To install gem add it:

Gemfile
1
2
3
group :development do
  gem 'capistrano-notifier'
end

After that you should add some settings to be able to send mails. Here is example for gmail:

config/deploy.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
set :notifier_mail_options, {
  :method => :smtp,
  :from   => 'capistrano@domain.com',
  :to     => ['john@doe.com', 'jane@doe.com'],
  :github => 'MyCompany/project-name',
  :smtp_settings => {
    address: "smtp.gmail.com",
    port: 587,
    domain: "gmail.com",
    authentication: "plain",
    enable_starttls_auto: true,
    user_name: MY_USERNAME,
    password: MY_PASSWORD
  }
}

After that each person, whose email has been provided in :to section will receive the email after deploy. Of course, you may need some time to set thins up properly, but afterwards this feature may be very handy for a lot of people.

capistrano_deploy_lock

Last, but not least hero is capistrano_deploy_lock. I think you should know that nothing good will ever come out of two (and more) simultaneously deploys. This modest hero helps to fight with such evil.

Installation is simple:

Gemfile
1
2
3
group :development do
  gem 'capistrano_deploy_lock'
end

Call the hero:

config/deploy.rb
1
require 'capistrano/deploy_lock'

Make sure that all developers have this gem and config to protect your deploys. Now each deploy would be locked during deploy and would be unlocked afterwards. This protects each your deploy from simultaneously deploys of other people. Each person, who would try to deploy during current deploy would receive this message (or something like this):

Terminal
1
2
3
*** Deploy locked 3 minutes ago by 'dark side'
*** Message: Deploying master branch
*** Expires in 12 minutes

This gem also helps in situations when your deploy fails, which gives you time to fix it (by default it is 15 minutes). This feature helped me few times. You can find more details in readme

That is all for today, thank you for your patience.

P.S. All these gems have been tested with Rails 4 and they work.

Comments