やる気がストロングZERO

やる気のストロングスタイル

railsのrake taskをcron実行する

普通にcrontabでこんな感じで設定したけど動かなかった。

*/10 * * * * cd /app && bundle exec rake rake:task RAILS_ENV=production

最終的にはwheneverというgemを使って解決した。 GitHub - javan/whenever: Cron jobs in Ruby

なぜ動かん?

cron実行の際の環境はいつもrake taskを実行している環境と色々異なる。

  • PATHの設定が足りなくて、bundleを見つけられない。
  • PATHを指定しても、railsで使ってる環境変数(DB設定とか。)が設定されていないので、railsのロードで失敗。

どうすればいいか?

3案くらいあるかと思った。

cronの設定で上部に全部書く。

PAHT=~~~~~~~~~~
DB_HOST=~~~~
DB_PORT=5432
...必要な物全部
*/10 * * * * cd /app && bundle exec rake rake:task RAILS_ENV=production

メリット:簡単・シンプル
デメリット:値の2重管理になる※cron設定はシェルじゃないので$PATHとかが展開されない。直接値を書く必要がある

cron実行前にbashrcとかを読み込むようにする(bashrcに必要な環境変数設定が書かれている場合)

*/10 * * * * source ~/.bashrc && cd /app && bundle exec rake rake:task RAILS_ENV=production

メリット:簡単・シンプル
デメリット:bashrcにかかれていないものは反映されない。今回はdocker-compose.ymlに環境変数を書いていて、それがコンテナ内でどこで書き込まれているのかよくわからんかった。(bashrcには記述がない。) 余計なものも色々実行されるのも不安かも

whenever(GEM)を使う。

rails用のcron設定を生成してくれる機能。 railsで使う環境変数も書き出しできる。

メリット:確実に動作するcron設定を出してくれる。2重管理にならない
デメリット:ちょっと複雑。

wheneverを使ってみた。

インストール

Gemfileに追記

gem 'whenever', require: false

初期化

bundle exec wheneverize .

を実行して設定ファイル(config/schedule.rb)作成。

設定記述

config/schedule.rbに記述追記

ENV.each { |k, v| env(k, v) } # 環境変数を全部設定する。※もっと丁寧にやったほうがいいかも。。
set :output, "/var/log/cron.log"

every '*/10 * * * *' do
  rake "rake:task"
end

cronに反映

bundle exec whenever # 事前にどういうcrontabになるのかを確認できる。

bundle exec whenever --update-crontab # crontabへ設定実行

crontab -l # 設定されたか確認