I already have a deploy.rb that can deploy my app on my production server.
My app contains a custom rake task (a .rake file in the lib/tasks directory).
I\
If you want to be able to pass multiple arguments try this (based on marinosbern's answer):
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
execute :rake, "#{args.command}[#{args.extras.join(",")}]"
end
end
end
end
Then you can run a task like so: cap production invoke["task","arg1","arg2"]
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
Previous answers didn't help me and i found this: From http://kenglish.co/run-rake-tasks-on-the-server-with-capistrano-3-and-rbenv/
namespace :deploy do
# ....
# @example
# bundle exec cap uat deploy:invoke task=users:update_defaults
desc 'Invoke rake task on the server'
task :invoke do
fail 'no task provided' unless ENV['task']
on roles(:app) do
within release_path do
with rails_env: fetch(:rails_env) do
execute :rake, ENV['task']
end
end
end
end
end
to run your task use
bundle exec cap uat deploy:invoke task=users:update_defaults
Maybe it will be useful for someone
...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
There's an interesting gem cape that makes your rake tasks available as Capistrano tasks, so you can run them remotely. cape
is well documented, but here's a short overview on how to set i up.
After installing the gem, just add this to your config/deploy.rb
file.
# config/deploy.rb
require 'cape'
Cape do
# Create Capistrano recipes for all Rake tasks.
mirror_rake_tasks
end
Now, you can run all you rake
tasks locally or remotely through cap
.
As an added bonus, cape
lets you set how you want to run your rake task locally and remotely (no more bundle exec rake
), just add this to your config/deploy.rb
file:
# Configure Cape to execute Rake via Bundler, both locally and remotely.
Cape.local_rake_executable = '/usr/bin/env bundle exec rake'
Cape.remote_rake_executable = '/usr/bin/env bundle exec rake'
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