Take the 2-minute tour ×

I'm using Capistrano to handle my deployment, and I've got two different roles in my setup - :web and :processing. They both have the usual :deploy tasks, but the :restart task needs to be different for the two types of server.

So my first attempt was something like this:

task :restart, :roles => :web do
    run "... web related restart stuff ..."

task :restart, :roles => :processing do
    run "... processing related restart stuff ..."

Which doesn't work, because the second :restart (for :processing role) replaces the first :restart (for the :web role), and the :web :restart never happens.

I had a quick look around to see if I could write conditional code depending on which role (or roles) a server might be in when the task is run but there's next to no documentation out there for that kind of thing. Any ideas?

share|improve this question
add comment

3 Answers

You should use namespaces:

namespace :web do
  desc "Restart web servers"
  task :restart, :roles => :web do
    # Restart Magic Here

namespace :process do
  desc "Restart process servers"
  task :restart, :roles => :process do
    # Restart magic here

# Optionally:
task :restart do

That's what you're looking for I think!

Also, to use these on the command line, you would use

$ cap <stage>           # (if using multistage)
$ cap web:restart       # Restarts web servers
$ cap process:restart   # Restarts process servers
$ cap restart           # Restarts both process and web servers

(Source: I'm the Capistrano maintainer.)

share|improve this answer
add comment

You should use 'parallel' instead of 'run' in this case:

task :restart do
  parallel do |session|
    session.when "in?(:web)", "...substitute run command contents here...."
    session.when "in?(:process)", "...substitute run command contents here...."

If you are going to use something except 'run' in different tasks you'd better stick to one of the other answers.

More info on 'parallel' command can be found here: https://github.com/capistrano/capistrano/wiki/2.x-DSL-Action-Invokation-Parallel

share|improve this answer
add comment

If you need to call the default deploy task, and do some custom restarting, etc. I came up with this solution:

# Servers
server "importerhost.com", :app, :web, :db, :importer, :primary => true
server "backuphost.com",   :app, :web, :db, :backup,   :primary => true
set :deploy_to, "/apps/appname"

# Ensure deploy before restart
before 'importer:deploy', 'deploy'
before 'backup:deploy',   'deploy'

# Importer
namespace :importer do
  desc "Restart importer service"
  task :deploy, :roles => :importer do
    sudo "cp #{current_release}/config/importer.conf /etc/init/importer.conf"
    sudo "service importer restart N=1"
    sudo "service importer restart N=2"

# Backup
namespace :backup do
  desc "Restart backup service"
  task :deploy, :roles => :backup do
    sudo "cp #{current_release}/config/backup.conf /etc/init/backup.conf"
    sudo "service backup restart"

And then simply deploy with cap ROLES=importer importer:deployor cap ROLES=backup backup:deploy. This gave me the freedom to deploy the same source code to different servers, and execute completely different tasks after the actual deployment.

share|improve this answer
add comment

Your Answer


