実現したいこと
ec2にデプロイしたrailsアプリケーションでrakeタスクを定期実行したい。
あまりいい記事が見つからなかったのでまとめました。
前提
2022年10月現在
ruby 3.1.2
Rails 6.1.6
whenever
ec2
capistranoを使ってデプロイ
手順
- Capistranoを適用する
- schedule.rbを編集する
- crontabをupdate
- タイムゾーンを変更する
- ec2上でエラーログを確認する方法
1, Capistranoに導入
capfileとdeploy.rbを編集する。
capfiel
require 'whenever/capistrano'
deploy.rb
set :whenever_roles, -> { :app }
2, schedule.rbを編集する
確認すべきポイントはrakeタスクの環境がproductionになっているか。
そしてec2はbashなので、zshを使うような設定を書いている場合は消しておく。(デフォルトはbashらしいので何も書かなくていい。)
schedule.rb
#環境変数の設定
set :environment, ENV['RAILS_ENV']
#以下のような記載がある場合はコメントアウトしておく。(ec2はbashなので)
#set :job_template, "/bin/zsh -l -c ':job'"
#以下はenvironmentの引数をENV['RAILS_ENV']にする。
#これでproduction環境の時、ENV['RAILS_ENV']に"produciton"が代入される。
every 1.day, at: '6:02' do
rake 'chatroom:create', environment: ENV['RAILS_ENV']
end
3, pushとデプロイ
ここまでの変更をpushして、ec2にもデプロイしておく。
git push
bundle exec cap production deploy
4, crontabをアップデートする
デプロイが済んだら、schedule.rbの変更をec2上のcronにも適用させる必要がある。
#アプリのパスで下記コマンドを実行
#現在のcrontabを確認
$ bundle exec whenever
# cronをアップデート
$ bundle exec whenever --update-crontab
# cronタブが変更されたか確認
$ crontab -l
変更されていなければ、ちゃんとpushしてec2にデプロイしたか確認すること。
5,タイムゾーンを変更する
以下は日本時間でスケジューラを実行したい場合に行う。
以下の操作は全てEC2のターミナルで行う。
$ date #現在時刻を確認する
=>UTCで時間が表示される
タイムゾーンを変更したい場合/etc/sysconfig/clock
というファイルがあるのでこれを編集する。
$ cd /etc/sysconfig
$ sudo vim clock
sysconfig/clock
を以下のように編集。
ZONE="Asia/Tokyo"
UTC=false
これで変更は完了。
変更したタイムゾーンを適用するにはcronの再起動とOSの再起動を行う必要がある。
#cronの再起動
$ sudo service crond restart
#OSの再起動
$ sudo reboot
補足 エラーログの確認方法
cronがうまくいかない場合はエラーログを確認したいだろう。
エラーログはec2上の/var/log/cronというファイルに書かれている。これを見るには下記コマンドを実行する。
#ec2のターミナルで実行
$ cd /var/log
$ sudo cat cron
これでうまくいきました。
参考にした記事
Capistranoに導入
【Ruby on Rails】EC2でwheneverを使ってcrontabを設定する時のハマったことの解決 - Qiita
ec2のcronにタイムゾーンを適用
AmazonLinux(EC2)で、crondにタイムゾーン変更を反映するにはOS再起動が必要 - Qiita
エラーログの確認方法
cronがうまく動作しているかチェックするためのログ調査方法について