运行 使用 Capistrano 3 进行 Cron 作业时以及 gem 时找不到 Gemfile

Gemfile not found when running Cron job with Capistrano 3 and whenever gem

我的 cron 作业在 运行 whenever -w 之后在我的本地机器上工作正常,在部署到我的 VPS 之后,我得到这个错误,release 20150415044915 doesn't exist。有什么想法吗?

我查看了我的 crontab -e,路径看起来也不错,其中 20150502114703 是正确的版本:

0 1 * * 1 /bin/bash -l -c 'cd /home/hey_production/releases/20150502114703 && bin/rails runner ....

错误日志:

/usr/local/rvm/gems/ruby-2.1.3/gems/bundler-1.7.3/lib/bundler/definition.rb:22:in `build': /home/hey_production/releases/20150415044915/Gemfile not found (Bundler::GemfileNotFound)
  from /usr/local/rvm/gems/ruby-2.1.3/gems/bundler-1.7.3/lib/bundler.rb:154:in `definition'
  from /usr/local/rvm/gems/ruby-2.1.3/gems/bundler-1.7.3/lib/bundler.rb:117:in `setup'
  from /usr/local/rvm/gems/ruby-2.1.3/gems/bundler-1.7.3/lib/bundler/setup.rb:17:in `<top (required)>'
  from /usr/local/rvm/rubies/ruby-2.1.3/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:135:in `require'
  from /usr/local/rvm/rubies/ruby-2.1.3/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:135:in `rescue in require'
  from /usr/local/rvm/rubies/ruby-2.1.3/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:144:in `require'
  from bin/rails:14:in `<main>' 

基本上缺少告诉 cron 在哪里寻找 Gemfile 的环境变量。因此您需要在 cron 尝试 运行 时在您的环境中添加该变量。 您可以在 schedule.rb:

env BUNDLE_GEMFILE, ENV["/home/hey_production/current/Gemfile"]

或直接在 crontab 文件中使用命令 crontab -e(在 cron 条目之前):

BUNDLE_GEMFILE="/home/hey_production/current/Gemfile"  

希望对您有所帮助。

编辑 忘记上面的符号 schedule.rb

schedule.rb中的那一行应该是这样的

env :BUNDLE_GEMFILE, ENV["/#{path}/Gemfile"]

env :BUNDLE_GEMFILE, ENV["/home/hey_production/current/Gemfile"]

作为对先前答案的跟进,在计划块之前的任何时候在 schedule.rb 中设置 env 变量,例如:

def production?
  @environment == 'production'
end

set :output, {:error => '/home/current/log/cron_error.log', :standard => '/home/current/log/cron.log'}

every 2.hour, roles: [:utility] do
  runner "/home/current/lib/cron_jobs/launch_pending_emails.rb"
end

并在您的 deploy.rb 环境特定文件中,即:staging.rb 设置环境:

set :whenever_roles, [:utility]
set :whenever_environment, defer { stage }
set(:whenever_command) { "STAGE=#{stage} bundle exec whenever" }
require 'whenever/capistrano'