Capistrano에서 레이크 작업을 실행하려면 어떻게해야합니까?


105

프로덕션 서버에 앱을 배포 할 수있는 deploy.rb가 이미 있습니다.

내 앱에는 사용자 지정 레이크 작업 (lib / tasks 디렉터리의 .rake 파일)이 포함되어 있습니다.

레이크 작업을 원격으로 실행할 캡 작업을 만들고 싶습니다.


2
누군가 카피 스트라 노 자체 #{rake}변수 를 사용하는 장단점을 설명 할 수 있습니까 ? 항상 최선의 선택은 아닌 것 같습니다.
lulalala

답변:


59

좀 더 명시 적으로에서 \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

1
/ usr / bin / env rake를 사용하는 것이 더 좋으므로 rvm 설정이 올바른 레이크를 선택합니다.
DGM

8
가능한 경우 '번들 간부'사용
Bogdan Gusiev 2011 년

44

... 몇 년 후 ...

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

3
이것은 카피 스트라 노 v3에만 해당됩니다.
phillbaker

많이 도왔습니다. 감사! @Mirek Rusin
Nishant Shrivastava

다른 대답은, 그 사용 run은 버전 2까지 카피 스트라 노에서 작동 할 것입니다. 버전 3에서 이것이 갈 길입니다.
Don Giulio 2015 년

44

Capistrano 3 Generic 버전 (모든 레이크 작업 실행)

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필요는 카피 스트라 노 레일 보석에서 온다


1
이것은 단지 바꿀 경우, 하나의 인자를 지원 rake args[:command] 하여 execute :rake, "#{args.command}[#{args.extras.join(",")}]" 다수의 인수 작업을 실행할 수 있습니다 당신과 같이 : cap production invoke["task","arg1","arg2"]
로빈 Clowers

1
@ Robin Clowers 여러 인수를 전달할 수 있습니다 (예 : cap staging invoke['task[arg1\,arg2]']. rake의 실제 호출을 반영하기 때문에 언급 한 방법보다이 방법을 선호합니다. 이 접근 방식을 사용하면 여러 작업을 연결할 수도 있으며, 이는 종종 유용합니다 cap staging invoke['task1 task2[arg1] task3[arg2\,arg3]']. 레이크 10.2.0 이상에서 작동
marinosb

이것은 훌륭합니다. 참고하고 싶습니다. : app을 서버 역할 중 하나로 포함해야합니다.
lfender6445

분명히 이것은 "invoke [db : migrate]"이어야합니다 ... 수정되었습니다.
Abram

@Abram 명령을 사용하여 "작업 'invoke를 빌드하는 방법을 모르겠습니다.'라는 메시지가 나타납니다.
dc10 dec

41
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내가 처음에 그것을 생각하지 않았고 작업이 아무것도되지 않은 이유를 알아낼 수 - 잡았다이었다.


2
약간의 개선점 : 세미콜론을 &&로 바꾸면 첫 번째 명령문 (디렉토리 변경)이 실패하면 두 번째 명령문 (rake 작업 실행)이 실행되지 않습니다.
Teflon Ted

2
여러 서버에 배포하는 경우 작동하지 않습니다. 레이크 작업을 여러 번 실행합니다.
Mark Redding

4
하나는 정말 카피 스트라 노의 레이크 설정을 존중해야"cd #{deploy_to}/current && #{rake} <task_name> RAILS_ENV=production"
kares

@Mark Redding : 레이크 작업을위한 자체 역할에 서버 중 하나를 배치하고 해당 역할이있는 서버에서만 실행되도록 capistrano 작업을 제한 할 수 있습니까?
mj1531

내 deploy.rb에서 작업을 만든 곳에서 뭔가를했습니다. 이 작업에는 : roles => : db가 있으므로 db : migrate의 기본 서버로 정의한 동일한 서버에서만 실행됩니다.
Mark Redding

20

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

2
이것이 가장 좋은 해결책이며 가능한 경우 카피 스트라 노 값을 사용합니다
loopj

2
당신이 사용해야 할 수도 있습니다 귀하의 작업이 네임 스페이스되는 경우 (즉,이 최상위 네임 스페이스에 정의되지 않았습니다) 고 덧붙였다 아마 가치가 top.run대신의run
dolzenko

감사합니다 @dolzenko. 방법에 대한 문서를top 찾았습니다 . run동일한 네임 스페이스에서 정의한 경우 top.run가 필요합니다. 그렇지 않으면 run태스크가 네임 스페이스가 지정된 경우에도 최상위 레벨을 찾아야합니다 . 내가 뭔가를 놓친 적이 있습니까? 사건에서 무슨 일이 있었나요?
captainpete 2013 년

1
동일한 네임 스페이스에 정의 된 실행 메서드가 없었기 때문에 필요한 이유가 확실하지 않습니다. 어떤 경우에는 카피 스트라 노 2.0은 역사와 다음 버전을 기반으로 레이크 (희망 일을 예측하고)입니다
dolzenko

16

capistrano-rake보석 사용

커스텀 카피 스트라 노 레시피를 엉망으로 만들지 않고 gem을 설치하고 다음과 같이 원격 서버에서 원하는 레이크 작업을 실행하십시오.

cap production invoke:rake TASK=my:rake_task

전체 공개 : 내가 썼다


7

개인적으로 프로덕션에서 다음과 같은 도우미 메서드를 사용합니다.

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 작업을 실행할 수 있습니다.


참고 : Duke가 제안한 것과 비슷 하지만 저는 :

  • current_release 대신 latest_release를 사용하십시오. 내 경험상 rake 명령을 실행할 때 기대하는 것이 더 많습니다.
  • Rake 및 Capistrano의 명명 규칙을 따릅니다 (대신 : cmd-> task 및 rake-> run_rake).
  • RAILS_ENV = # {rails_env}를 설정하지 마십시오. 올바른 위치는 default_run_options 변수이기 때문입니다. 예 : default_run_options [: env] = { 'RAILS_ENV'=> 'production'} #-> DRY!

5

갈퀴 작업을 Capistrano 작업으로 사용할 수있게 해주는 흥미로운 보석 망토 가 있으므로 원격으로 실행할 수 있습니다. cape잘 문서화되어 있지만 여기에 i를 설정하는 방법에 대한 간략한 개요가 있습니다.

gem을 설치 한 후 이것을 config/deploy.rb파일에 추가 하십시오.

# config/deploy.rb
require 'cape'
Cape do
  # Create Capistrano recipes for all Rake tasks.
  mirror_rake_tasks
end

이제 rake.NET을 통해 모든 작업을 로컬 또는 원격으로 실행할 수 있습니다 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'

참고 : Capistrano v2.x에서만 작동합니다. Capistrano v3와 호환되지 않습니다.
nayiaw

3
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 

1
좋은. 에서 변경 RAILS_ENV=production하는 것은 RAILS_ENV=#{rails_env}뿐만 아니라 내 준비 서버에서 작업을 할 수 있습니다.
evanrmurphy 2013 년

2

레이크 작업 실행을 단순화하기 위해 deploy.rb에 넣은 내용은 다음과 같습니다. 카피 스트라 노의 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'

카피 스트라 노가 자신의 레이크 변수 (사용할 레이크를 결정하는 데 사용됨)를 정의하므로 이러한 충돌은 예를 들어 자산을 사전 컴파일하는 영수증에 내장 된 영수증을 중단합니다
Michael

2

이것은 나를 위해 일했습니다.

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]"


1

대부분은 위의 답변 에서 나온 것입니다. 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

1

이것은 또한 작동합니다 :

run("cd #{release_path}/current && /usr/bin/rake <rake_task_name>", :env => {'RAILS_ENV' => rails_env})

더 많은 정보 : Capistrano Run


1
{deploy_to} / current는 여기서 작동하지 않습니다. 심볼릭 링크는 변경되지 않았습니다. rake task를 업데이트하면 이전 코드가 실행됩니다. 대신 {release_path} 사용을 고려하십시오.
Mark Redding 2011 년

더 많은 정보가 스팸입니까?
hcarreras

1

여러 인수를 전달할 수 있으려면 다음을 시도하십시오 (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"]


0

그래서 저는이 작업을 해왔습니다. 이음새가 잘 작동합니다. 그러나 코드를 실제로 활용하려면 포맷터가 필요합니다.

포맷터를 사용하지 않으려면 로그 수준을 디버그 모드로 설정하면됩니다. 이 세마는 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 :: Command 메서드를 변경했기 때문에 이렇게 말합니다.

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

0

이전 답변이 도움이되지 않았고 다음을 찾았습니다. 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

작업 사용을 실행하려면

bundle exec cap uat deploy:invoke task=users:update_defaults

누군가에게 유용 할 수도 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.