How do I run a rake task from Capistrano?

2020-01-25 04:00发布

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'd like to create a cap task that will remotely run that rake task.

16条回答
▲ chillily
2楼-- · 2020-01-25 04:25

I personally use in production a helper method like this:

def run_rake(task, options={}, &block)
  command = "cd #{latest_release} && /usr/bin/env bundle exec rake #{task}"
  run(command, options, &block)
end

That allows to run rake task similar to using the run (command) method.


NOTE: It is similar to what Duke proposed, but I:

  • use latest_release instead of current_release - from my experience it is more what you expect when running a rake command;
  • follow the naming convention of Rake and Capistrano (instead of: cmd -> task and rake -> run_rake)
  • don't set RAILS_ENV=#{rails_env} because the right place to set it is the default_run_options variable. E.g default_run_options[:env] = {'RAILS_ENV' => 'production'} # -> DRY!
查看更多
混吃等死
3楼-- · 2020-01-25 04:26
namespace :rake_task do
  task :invoke do
    if ENV['COMMAND'].to_s.strip == ''
      puts "USAGE: cap rake_task:invoke COMMAND='db:migrate'" 
    else
      run "cd #{current_path} && RAILS_ENV=production rake #{ENV['COMMAND']}"
    end
  end                           
end 
查看更多
聊天终结者
4楼-- · 2020-01-25 04:27

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
查看更多
SAY GOODBYE
5楼-- · 2020-01-25 04:28

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

查看更多
登录 后发表回答