我已经有一个deploy.rb可以在我的生产服务器上部署我的应用程序.
我的应用程序包含一个自定义rake任务(lib/tasks目录中的.rake文件).
我想创建一个能够远程运行该rake任务的上限任务.
更明确一点,在您的\config\deploy.rb
外部添加任何任务或命名空间:
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
然后,从/rails_root/
,您可以运行:
cap staging rake:invoke task=rebuild_table_abc
Capistrano 3通用版(运行任何rake任务)
构建Mirek Rusin的通用版本的答案:
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
用法示例: cap staging "invoke[db:migrate]"
请注意,deploy:set_rails_env
要求来自capistrano-rails gem
run("cd #{deploy_to}/current && /usr/bin/env rake `` RAILS_ENV=production")
发现它与谷歌 - http://ananelson.com/said/on/2007/12/30/remote-rake-tasks-with-capistrano/
这RAILS_ENV=production
是一个陷阱 - 我一开始并没有想到它,也无法弄清楚为什么任务没有做任何事情.
......几年后......
看看capistrano的rails插件,你可以在https://github.com/capistrano/rails/blob/master/lib/capistrano/tasks/migrations.rake#L5-L14看到它看起来像:
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
有一种常见的方式可以"与" require 'bundler/capistrano'
和其他修改rake的扩展一起工作.如果您使用多级,这也适用于预生产环境.要旨?如果可以,请使用config vars.
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
capistrano-rake
宝石只需安装gem而不会弄乱自定义capistrano配方,并在远程服务器上执行所需的rake任务,如下所示:
cap production invoke:rake TASK=my:rake_task
完全披露:我写了
我个人在生产中使用这样的辅助方法:
def run_rake(task, options={}, &block) command = "cd #{latest_release} && /usr/bin/env bundle exec rake #{task}" run(command, options, &block) end
这允许运行类似于使用run(command)方法的rake任务.
注意:它类似于杜克提出的,但我:
使用latest_release而不是current_release - 根据我的经验,它更像你在运行rake命令时所期望的;
遵循Rake和Capistrano的命名约定(而不是:cmd - > task和rake - > run_rake)
不要设置RAILS_ENV =#{rails_env},因为设置它的正确位置是default_run_options变量.例如default_run_options [:env] = {'RAILS_ENV'=>'production'}# - >干!
有一个有趣的宝石斗篷,使你的rake任务可用作Capistrano任务,所以你可以远程运行它们.cape
有详细记录,但这里有一个关于如何设置我的简短概述.
安装gem之后,只需将其添加到您的config/deploy.rb
文件中即可.
# config/deploy.rb require 'cape' Cape do # Create Capistrano recipes for all Rake tasks. mirror_rake_tasks end
现在,您可以在rake
本地或远程运行所有任务cap
.
作为一个额外的好处,cape
让您可以设置本地和远程运行rake任务的方式(不再需要bundle exec rake
),只需将其添加到您的config/deploy.rb
文件中:
# 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'