问题描述
我正在尝试使用适用于我的 Rails 应用程序的 Every gem 运行重复性任务。它在使用 Docker Compose 创建并托管在 Ubuntu 服务器上的 Docker 容器中运行。
我可以使用每当 gem 成功创建和更新 crontab 文件,但它似乎没有执行任务。
我想在应用运行时在后台重复执行的任务是:
rake searchkick:reindex CLASS=Property
我通常在使用 'docker-compose run web bash' 创建 web 运行容器后从终端成功执行此命令。这会使用 searchkick gem 重新索引我的 ElasticSearch 服务器。
相关版本如下:
- ruby 2.7.2p137
- rails (6.0.3.6)
- elasticsearch (6.8.3)
- elasticsearch-api (= 6.8.3)
- elasticsearch-transport (= 6.8.3)
- searchkick (4.4.4)
- activemodel (>= 5)
- elasticsearch (>= 6)
- hashie
- whenever (1.0.0)
- chronic (>= 0.6.3)
Cron 是使用 Dockerfile 安装的:
RUN apt-get update -qq && \
apt-get install -y curl \
build-essential \
libpq-dev \
cron \
vim \
nano \
postgresql \
postgresql-contrib \
postgresql-client
Dockerfile 在容器创建时运行一个脚本:
copY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
脚本 (entrypoint.sh) 创建一个 crontab 文件。
#!/bin/bash
set -e
# For development check if the gems as installed,if not,then uninstall them.
if ! [ bundle check ]; then
bundle install
fi
# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid
# Yarn - Check Files.
yarn install --check-files
# Create empty crontab file.
crontab -l | { cat; echo ""; } | crontab -
# Update crontab file using whenever command.
bundle exec whenever --set 'environment=production' --update-crontab
# Run the command - runs any arguements passed into this entrypoint file.
exec "$@"
上面的 'bundle exec Every --set 'environment=production' --update-crontab' 命令根据下面的 schedule.rb 文件更新 crontab 文件:
set :output,"log/cron_log.log"
env :PATH,ENV['PATH']
# Reindex Property records every 3 mins.
every 3.minutes do
rake "searchkick:reindex CLASS=Property"
end
我也试过使用这个:
every 3.minutes do
command "cd /myapp && rake searchkick:reindex CLASS=Property"
end
当我执行 'docker-compose run web bash' 以使用 rails 终端时,我在最后看到了这个响应:
no crontab for root
[write] crontab file updated
为了检查它是否正确创建,我使用“crontab -l”查看 rails 应用程序中的 crontab 文件,它显示:
# Begin Whenever generated tasks for: /myapp/config/schedule.rb at: 2021-04-24 13:07:12 +0000
PATH=/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57 * * * * /bin/bash -l -c 'cd /myapp && RAILS_ENV=production bundle exec rake searchkick:reindex CLASS=Property --silent >> log/cron_log.log 2>&1'
# End Whenever generated tasks for: /myapp/config/schedule.rb at: 2021-04-24 13:07:12 +0000
更新:使用cron service status
和cron service start
后,myApp/log/cron_log.log中的日志显示如下:
bundler: Failed to load command: rake (/usr/local/bin/rake)
Bundler::GemNotFound: Could not find rake-13.0.3 in any of the sources
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:86:in `block in materialize'
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:80:in `map!'
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:80:in `materialize'
/usr/local/lib/ruby/2.7.0/bundler/deFinition.rb:170:in `specs'
/usr/local/lib/ruby/2.7.0/bundler/deFinition.rb:237:in `specs_for'
/usr/local/lib/ruby/2.7.0/bundler/deFinition.rb:226:in `requested_specs'
/usr/local/lib/ruby/2.7.0/bundler/runtime.rb:101:in `block in deFinition_method'
/usr/local/lib/ruby/2.7.0/bundler/runtime.rb:20:in `setup'
/usr/local/lib/ruby/2.7.0/bundler.rb:149:in `setup'
/usr/local/lib/ruby/2.7.0/bundler/setup.rb:20:in `block in <top (required)>'
/usr/local/lib/ruby/2.7.0/bundler/ui/shell.rb:136:in `with_level'
/usr/local/lib/ruby/2.7.0/bundler/ui/shell.rb:88:in `silence'
/usr/local/lib/ruby/2.7.0/bundler/setup.rb:20:in `<top (required)>'
bundler: Failed to load command: rake (/usr/local/bin/rake)
Bundler::GemNotFound: Could not find rake-13.0.3 in any of the sources
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:86:in `block in materialize'
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:80:in `map!'
/usr/local/lib/ruby/2.7.0/bundler/spec_set.rb:80:in `materialize'
/usr/local/lib/ruby/2.7.0/bundler/deFinition.rb:170:in `specs'
/usr/local/lib/ruby/2.7.0/bundler/deFinition.rb:237:in `specs_for'
/usr/local/lib/ruby/2.7.0/bundler/deFinition.rb:226:in `requested_specs'
/usr/local/lib/ruby/2.7.0/bundler/runtime.rb:101:in `block in deFinition_method'
/usr/local/lib/ruby/2.7.0/bundler/runtime.rb:20:in `setup'
/usr/local/lib/ruby/2.7.0/bundler.rb:149:in `setup'
/usr/local/lib/ruby/2.7.0/bundler/setup.rb:20:in `block in <top (required)>'
/usr/local/lib/ruby/2.7.0/bundler/ui/shell.rb:136:in `with_level'
/usr/local/lib/ruby/2.7.0/bundler/ui/shell.rb:88:in `silence'
/usr/local/lib/ruby/2.7.0/bundler/setup.rb:20:in `<top (required)>'
所以它似乎已经设置了 crontab 文件并且 cronjob 正在尝试运行但它没有找到 rake-13.0.3。我将检查这是否是 bundler gem 版本与 gemfile 中内容的问题。
感谢任何帮助。
解决方法
- 您可以在您的
cron
中运行entrypoint.sh
来启动 cron 服务 (linux)
# Update crontab file using whenever command.
cron && bundle exec whenever --set 'environment=production' --update-crontab
- schedule 不知道 gems 路径,因此抛出
Bundler::GemNotFound
错误,要解决此问题,您可以通过在schedule.rb
中设置所有 ENV 来避免丢失路径
set :output,"log/cron_log.log"
ENV.each { |k,v| env(k,v) }
# ...