Railsのバッチ処理のcrontab設定をwhenever&capistranoで自動化
Railsアプリのデプロイ自体はcapistranoで行う事が多いが
バッチ処理のcron設定もwheneverを使ってruby側で行う事で一元管理できる。
さらにcapistranoと連携する事でデプロイ時のcrantab設定まで自動化してみる。
設定漏れも防げるし、管理もすっきりするのでいいことずくめ。
wheneverインストール
Gemfileに以下を追加
gem 'whenever', :require => false
railsプロジェクトにインストール
bundle install --path vendor/bundle
以下を実行してschedule.rbを作成
bundle exec wheneverize .
作成したschedule.rbを編集する
- outputを定義するとログの出力先を指定できる
- environmentを定義すると環境変数を利用できる
- crontabの指定は以下のような形でrails風な感じでもcrontab風でもOK
-
job_typeを定義してPATHの定義等カスタマイズする事も可能
set :output, 'log/crontab.log' set :environment, @environment job_type :runner, "export PATH=\"$HOME/.rbenv/bin:$PATH\"; eval \"$(rbenv init -)\"; cd :path && RAILS_ENV=:environment bundle exec rails runner :task :output" every 1.day, :at => '1:30 am' do command "sh batches/main.sh" end every 1.day, :at => '22:00 pm' do runner "Tasks::Testbatch.execute" end every :month, :at => '1:00 am' do rake "batch:samplerake" end
作成して以下を実行するとcrontabに記述されるスケジュールが表示される(この時点では実際には登録されない)
bundle exec whenever --set environment=development
しかしエラーが発生した。
uninitialized constant Whenever::JobList::Tasks (NameError)
Tasksが見つけられないとの事なので以下をschedule.rbに追加
require File.expand_path(File.dirname(__FILE__) + "/environment.rb")
再度[bundle exec whenever]するとcrontab用のテキストが表示された
実際にcrontabに反映するには以下のコマンドを実行する
bundle exec whenever --update-crontab --set environment=development
jobを削除するコマンド(crontabの他jobには影響はない)
bundle exec whenever --clear-crontab --set environment=development
capistranoと連携
とりあえずwheneverを使ってcrontabの設定を出来るようになったので
capistranoに組み込んでデプロイ時に自動反映出来るようにする。
capistranoをインストール
gem install capistrano -v '~>2.15'
※rbenv環境下の場合は以下のような感じでPATHにrbenvを加える
PATH="$HOME/.rbenv/bin:$PATH" sudo gem install capistrano -v '~>2.15'
設定ファイル生成コマンド(アプリケーションルートディレクトリで実行)
capify .
deploy.rbを編集する
細かい設定は使い方はこちらで
https://github.com/capistrano/capistrano
wheneverの設定を追加するためにdeploy.rbを編集
require 'whenever/capistrano'
set :whenever_command, "bundle exec whenever"
set :whenever_environment, defer {'staging'}
set :whenever_roles,defer{"IPADDR:PORT"}
after 'deploy:update', 'whenever:update_crontab'
設定が出来たら試してみる
cap staging deploy
エラーが発生。
Net::SSH::AuthenticationFailed: Authentication failed
以下を参考にnet-sshをバージョン下げて再インストールした
http://stackoverflow.com/questions/21811026/capistrano-cannot-deploy-code-because-netsshauthenticationfailed-authentic
gem uninstall net-ssh -v 2.8.0
gem install net-ssh -v 2.7.0
今度は動いたんだけどwhenever:update_crontab
が空振りしてしまう。。。
こちらを参考に上のwhenever_xxxのパラメータ設定を変更
http://stackoverflow.com/questions/21395839/whenever-gem-failing-on-deploy
role :web, target_ip
set :whenever_roles, ->{ :web }
set :whenever_options, ->{ {:roles => fetch(:whenever_roles)} }
set :whenever_command, ->{"bundle exec whenever"}
set :whenever_identifier, ->{ fetch :application }
set :whenever_environment, ->{ fetch :rails_env, "production" }
set :whenever_variables, ->{ "environment=#{fetch :whenever_environment}" }
set :whenever_update_flags, ->{ "--update-crontab #{fetch :whenever_identifier} --set #{fetch :whenever_variables}" }
set :whenever_clear_flags, ->{ "--clear-crontab #{fetch :whenever_identifier}" }
これで無事動いた。
設定自体はたいした事無いんだけど、色々ハマった。。。