Friday, August 03, 2007

Mongrel and Capistrano 2.0

I use Capistrano, and Mongrel. Mongrel comes prepackaged with capistrano 1.4 recipes for stopping and starting, making it a cinch to roll a new version and stop and start your service.

Capistrano 2.0 has just been released, and mongrel hasn't yet been updated. The solution is to roll your own tasks for mongrel. You can do this by adding the following to your project's deploy.rb file.

Update: minor bug fixed in code. Thanks to funkdoobiest for pointing it out.

Update: mongrel_conf may need to be defined in your deploy.rb as meekish points out in the comments.

set :mongrel_conf, "#{deploy_to}/current/config/mongrel_cluster.yml"


namespace :deploy do
  namespace :mongrel do
    [ :stop, :start, :restart ].each do |t|
      desc "#{t.to_s.capitalize} the mongrel appserver"
      task t, :roles => :app do
        #invoke_command checks the use_sudo variable to determine how to run the mongrel_rails command
        invoke_command "mongrel_rails cluster::#{t.to_s} -C #{mongrel_conf}", :via => run_method
      end
    end
  end

  desc "Custom restart task for mongrel cluster"
  task :restart, :roles => :app, :except => { :no_release => true } do
    deploy.mongrel.restart
  end

  desc "Custom start task for mongrel cluster"
  task :start, :roles => :app do
    deploy.mongrel.start
  end

  desc "Custom stop task for mongrel cluster"
  task :stop, :roles => :app do
    deploy.mongrel.stop
  end

end

Capistano already has tasks for deploy:restart, deploy:start, and deploy:stop. What the code above does is add the following tasks:


deploy:mongrel:start
deploy:mongrel:restart
deploy:mongrel:stop

It then overrides the default deploy:restart, deploy:start, and deploy:stop tasks to call the mongrel ones.

So now the following commands: stop, start and restart your mongrel servers respectively.

cap deploy:stop
cap deploy:start
cap deploy:restart

17 comments:

Ciara Lee said...

I just discovered the magic of capistrano, mongrel, and nginx last night. It's pretty nice to just run 'cap deploy' and watch it all happen :)

funkdoobiest said...

hi john,

thank you for this nice receipes!
little bug in line 5:

change:
task t do
to:
task t, :role => :app do

so mongrel restart goes not to the database :)

Cengal said...

funkdoobiest,
well spotted. My db and appserver are one in the same so I never noticed.

John

Dru said...

Very helpful, my cap is deploying
cleanly now. Thanks!

Ahsan said...

Thanks for this useful tip !

koba said...

Wow. I've been googlin' for something like this for a while. I can't believe your post isn't the first hit.

This is great! Thanks! A very clean and useful implementation!

More excalmation points: !!!

(your comment box thinks "exclamation" is spelled wrong...)

Thanks,
Koba

Cengal said...

Hi Koba,
Thanks for the comment. If you link to my post it will help get it up the page rank.

John

Rafael said...

wonderful, thank your for this recipe.
Capistrano 2.1 back to life again :-)

Petar said...

Using your recipe also. Thank you!

daxhuiberts said...

Thank you so much,
This is the cleanest sollution I found for enabling capistrano 2 with mongrel cluster.

meekish said...

mongrel_conf was not defined in my deploy.rb task, so I added this:

set :mongrel_conf, "#{deploy_to}/current/config/mongrel_cluster.yml"

PackMaster said...

I also needed the mongrel_cluster variable - you might want to note it above.

GREAT HELP - THANKS SO MUCH!

Cengal said...

meekish, many thanks for your comment. I added an update to the text above.

AnĂ­bal said...

Beautiful code, it keeps the deployment recipe very clean, thank you.

Off Topic: Please feel free to register this blog at RubyCorner.com, the directory for blogs related to the Ruby Programming Language or any of the related technologies.

Cengal said...

Hi Anibal,
Cheers for your comment. Had a look at RubyCorner. Its a valuable resource so thanks for the pointer.

John

Anonymous said...

the other thing to think about on restart is that the mongrel_rails cluster::restart command won't change working directory to your newly deployed code base with unpredictable results. You might want to implement restart in terms of calling stop and then start.

Anonymous said...

*** [err :: test.foobar] ERROR RUNNING 'cluster::restart': Plugin /cluster::restart does not exist in category /commands