How do I run a rake task from Capistrano?

A little bit more explicit, in your \config\deploy.rb, add outside any task or namespace:

namespace :rake do  
  desc "Run a task on a remote server."  
  # run like: cap staging rake:invoke task=a_certain_task  
  task :invoke do  
    run("cd #{deploy_to}/current; /usr/bin/env rake #{ENV['task']} RAILS_ENV=#{rails_env}")  
  end  
end

Then, from /rails_root/, you can run:

cap staging rake:invoke task=rebuild_table_abc

Capistrano 3 Generic Version (run any rake task)

Building a generic version of Mirek Rusin's answer:

desc 'Invoke a rake command on the remote server'
task :invoke, [:command] => 'deploy:set_rails_env' do |task, args|
  on primary(:app) do
    within current_path do
      with :rails_env => fetch(:rails_env) do
        rake args[:command]
      end
    end
  end
end

Example usage: cap staging "invoke[db:migrate]"

Note that deploy:set_rails_env requires comes from the capistrano-rails gem


...couple of years later...

Have a look at capistrano's rails plugin, you can see at https://github.com/capistrano/rails/blob/master/lib/capistrano/tasks/migrations.rake#L5-L14 it can look something like:

desc 'Runs rake db:migrate if migrations are set'
task :migrate => [:set_rails_env] do
  on primary fetch(:migration_role) do
    within release_path do
      with rails_env: fetch(:rails_env) do
        execute :rake, "db:migrate"
      end
    end
  end
end

run("cd #{deploy_to}/current && /usr/bin/env rake `<task_name>` RAILS_ENV=production")

Found it with Google -- http://ananelson.com/said/on/2007/12/30/remote-rake-tasks-with-capistrano/

The RAILS_ENV=production was a gotcha -- I didn't think of it at first and couldn't figure out why the task wasn't doing anything.


Use Capistrano-style rake invocations

There's a common way that'll "just work" with require 'bundler/capistrano' and other extensions that modify rake. This will also work with pre-production environments if you're using multistage. The gist? Use config vars if you can.

desc "Run the super-awesome rake task"
task :super_awesome do
  rake = fetch(:rake, 'rake')
  rails_env = fetch(:rails_env, 'production')

  run "cd '#{current_path}' && #{rake} super_awesome RAILS_ENV=#{rails_env}"
end