문제

이미 제작 서버에 내 앱을 배포 할 수있는 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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top