Capistrano에서 레이크 작업을 어떻게 실행합니까?
-
10-07-2019 - |
문제
이미 제작 서버에 내 앱을 배포 할 수있는 deploy.rb가 이미 있습니다.
내 앱에는 사용자 정의 레이크 작업이 포함되어 있습니다 (lib/tasks 디렉토리의 .rake 파일).
그 레이크 작업을 원격으로 실행하는 캡 작업을 만들고 싶습니다.
해결책 2
run("cd #{deploy_to}/current && /usr/bin/env rake `<task_name>` RAILS_ENV=production")
Google에서 찾았습니다. http://ananelson.com/said/on/2007/12/30/remote-rake-tasks-with-capistrano/
그만큼 RAILS_ENV=production
Gotcha였습니다. 처음에는 생각하지 않았고 작업이 왜 아무것도하지 않았는지 알 수 없었습니다.
다른 팁
당신의 약간 더 명시 적 \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의 Rails 플러그인을 살펴보십시오. https://github.com/capistrano/rails/blob/master/lib/capistrano/tasks/migrations.rak#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
Capistrano 3 일반 버전 (갈퀴 작업 실행)
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 보석에서 나옵니다
Capistrano 스타일 레이크 호출을 사용하십시오
"그냥 작동"하는 일반적인 방법이 있습니다. require 'bundler/capistrano'
갈퀴를 수정하는 다른 확장. 다중 스테이지를 사용하는 경우 사전 생산 환경에서도 작동합니다. 요점? 가능한 경우 구성 대표를 사용하십시오.
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
보석
Custom Capistrano 레시피를 엉망으로 만들지 않고 보석을 설치하고 다음과 같은 원격 서버에서 원하는 레이크 작업을 실행하십시오.
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
이를 통해 실행 (명령) 메소드를 사용하는 것과 유사한 레이크 작업을 수행 할 수 있습니다.
참고 : 그것은 무엇과 유사합니다 공작 제안되었지만 i :
- current_release 대신 최신 _release를 사용하십시오 - 내 경험에서 그것은 레이크 명령을 실행할 때 기대하는 것입니다.
- Rake and Capistrano의 이름 지정 규칙을 따르십시오 (CMD-> 작업 및 레이크 -> Run_Rake 대신)
- RAILS_ENV =#{RAILS_ENV}를 설정하지 마십시오. 예를 들어 DEFAULT_RUN_OPTIONS [: ENV] = { 'RAILS_ENV'=> 'Production'} # -> Dry!
흥미로운 보석이 있습니다 ...곶 따라서 레이크 작업을 Capistrano 작업으로 사용할 수있게되므로 원격으로 실행할 수 있습니다. cape
잘 문서화되어 있지만 다음은 I를 설정하는 방법에 대한 짧은 개요가 있습니다.
보석을 설치 한 후에는 이것을 귀하의 config/deploy.rb
파일.
# config/deploy.rb
require 'cape'
Cape do
# Create Capistrano recipes for all Rake tasks.
mirror_rake_tasks
end
이제 모든 것을 실행할 수 있습니다 rake
로컬 또는 원격으로 작업 cap
.
추가 보너스로 cape
레이크 작업을 현지 및 원격으로 실행하는 방법을 설정할 수 있습니다 (더 이상 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'
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
Rake Rake 작업을 단순화하기 위해 Deploy.rb에 넣은 내용은 다음과 같습니다. Capistrano의 Run () 메소드 주변의 간단한 래퍼입니다.
def rake(cmd, options={}, &block)
command = "cd #{current_release} && /usr/bin/env bundle exec rake #{cmd} RAILS_ENV=#{rails_env}"
run(command, options, &block)
end
그런 다음 나는 그와 같은 갈퀴 작업을 실행합니다.
rake 'app:compile:jammit'
이것은 나를 위해 효과가있었습니다.
task :invoke, :command do |task, args|
on roles(:app) do
within current_path do
with rails_env: fetch(:rails_env) do
execute :rake, args[:command]
end
end
end
end
그런 다음 단순히 실행됩니다 cap production "invoke[task_name]"
그것의 대부분은 왔습니다 위의 답변 Capistrano에서 갈퀴 작업을 실행하기위한 사소한 향상
Capistrano에서 갈퀴 작업을 실행하십시오
$ cap rake -s rake_task=$rake_task
# Capfile
task :rake do
rake = fetch(:rake, 'rake')
rails_env = fetch(:rails_env, 'production')
run "cd '#{current_path}' && #{rake} #{rake_task} RAILS_ENV=#{rails_env}"
end
이것은 또한 작동합니다 :
run("cd #{release_path}/current && /usr/bin/rake <rake_task_name>", :env => {'RAILS_ENV' => rails_env})
더 많은 정보: Capistrano 달리기
여러 인수를 전달하려면 이것을 시도하십시오 (Marinosbern의 답변에 따라) :
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
그런 다음 다음과 같은 작업을 실행할 수 있습니다. cap production invoke["task","arg1","arg2"]
그래서 나는 이것에 대해 노력하고 있습니다. 잘 작동합니다. 그러나 코드를 실제로 활용하려면 포뮬레이터가 필요합니다.
Formatter를 사용하지 않으려면 로그 레벨을 디버그 모드로 설정하십시오. 이 Semas는 h
SSHKit.config.output_verbosity = Logger::DEBUG
캡 물건
namespace :invoke do
desc 'Run a bash task on a remote server. cap environment invoke:bash[\'ls -la\'] '
task :bash, :execute do |_task, args|
on roles(:app), in: :sequence do
SSHKit.config.format = :supersimple
execute args[:execute]
end
end
desc 'Run a rake task on a remote server. cap environment invoke:rake[\'db:migrate\'] '
task :rake, :task do |_task, args|
on primary :app do
within current_path do
with rails_env: fetch(:rails_env) do
SSHKit.config.format = :supersimple
rake args[:task]
end
end
end
end
end
이것은 위의 코드로 작업하기 위해 제작 한 형태입니다. SSHKIT에 내장 된 TextSimple을 기반으로하지만 사용자 정의 작업을 호출하는 나쁜 방법은 아닙니다. 오, 이것은 많은 사람들이 SSHKIT GEM의 최신 버전과 함께 작동하지 않습니다. 나는 그것이 1.7.1에서 작동한다는 것을 알고 있습니다. 마스터 브랜치가 사용할 수있는 sshkit :: 명령 메소드를 변경했기 때문에 이것을 말합니다.
module SSHKit
module Formatter
class SuperSimple < SSHKit::Formatter::Abstract
def write(obj)
case obj
when SSHKit::Command then write_command(obj)
when SSHKit::LogMessage then write_log_message(obj)
end
end
alias :<< :write
private
def write_command(command)
unless command.started? && SSHKit.config.output_verbosity == Logger::DEBUG
original_output << "Running #{String(command)} #{command.host.user ? "as #{command.host.user}@" : "on "}#{command.host}\n"
if SSHKit.config.output_verbosity == Logger::DEBUG
original_output << "Command: #{command.to_command}" + "\n"
end
end
unless command.stdout.empty?
command.stdout.lines.each do |line|
original_output << line
original_output << "\n" unless line[-1] == "\n"
end
end
unless command.stderr.empty?
command.stderr.lines.each do |line|
original_output << line
original_output << "\n" unless line[-1] == "\n"
end
end
end
def write_log_message(log_message)
original_output << log_message.to_s + "\n"
end
end
end
end