簡単に定時処理が書ける便利なgem「whenever」
dockerでアプリ作成時、wheneverを使った処理をしようとしたが、つまづいてしまったので忘備録として記述しておきます。
#環境
Ruby 2.5.1
Rails 5.2.4.3
#やりたいこと
今回はpostというモデルを用意し、wheneverを使って1分ごとにpostを作成してみる。
dockerの環境構築は終わっているものとしてスタート。
##modelとcontrollerを作成
docker上で
root@6181bdf78fa7:/myapp# bundle exec rails g model post name:string
root@6181bdf78fa7:/myapp# bundle exec db:migrate
root@6181bdf78fa7:/myapp# bundle exec rails g controller posts
##wheneverの設定
まずはgemをインストール
gem 'whenever', require: false
buildし直してgemをインストールしたらコマンドを実行してファイルを作成
root@6181bdf78fa7:/myapp# bundle exec wheneverize .
[add] writing `./config/schedule.rb'
[done] wheneverized!
作成されたschedule.rbに処理をかいていきます。
require File.expand_path(File.dirname(__FILE__) + "/environment")
set :environment, :development
set :output, 'log/cron.log'
ENV.each { |k, v| env(k, v) }
every 1.minutes do
runner "Post.create"
end
ここまできたら、cronに設定を反映させる
root@6181bdf78fa7:/myapp# bundle exec whenever --update-crontab
bundler: failed to load command: whenever (/usr/local/bundle/bin/whenever)
Errno::ENOENT: No such file or directory - crontab
/usr/local/bundle/gems/whenever-1.0.0/lib/whenever/command_line.rb:77:in `popen'
/usr/local/bundle/gems/whenever-1.0.0/lib/whenever/command_line.rb:77:in `write_crontab'
/usr/local/bundle/gems/whenever-1.0.0/lib/whenever/command_line.rb:38:in `run'
/usr/local/bundle/gems/whenever-1.0.0/lib/whenever/command_line.rb:6:in `execute'
/usr/local/bundle/gems/whenever-1.0.0/bin/whenever:44:in `<top (required)>'
/usr/local/bundle/bin/whenever:23:in `load'
/usr/local/bundle/bin/whenever:23:in `<top (required)>'
エラーが出ましたね。
cron初心者の自分はここでつまづいてしまいました。
##cronをインストール
どうやらdocker環境にcronをインストールしないといけないので、インストールに必要な処理をdockerfileに記述。
今回はこんな感じで1行追記しました。
FROM ruby:2.5.1
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN apt-get install -y cron #この行を追記
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
root@6710f08a3504:/myapp# bundle exec whenever --update-crontab
[write] crontab file updated
無事updateされてcronに反映されました。
これで自動処理が始まってると思い、しばらく待ってみます…
…どうやら動いてないですね。
wheneverが作動していればclog/cron.logが作成されるはずなので。
cronを起動させる
cronが動いていないので状態を確認します。
root@827fe138767f:/myapp# service cron status
[FAIL] cron is not running ... failed!
やはり動いていませんでした。
起動しましょう。
root@827fe138767f:/myapp# service cron start
[ ok ] Starting periodic command scheduler: cron.
1分後…
Running via Spring preloader in process 122
ついにcron.logが生成されlogが書かれました。
rails consoleで確認します。
root@827fe138767f:/myapp# bundle exec rails c
Running via Spring preloader in process 135
Loading development environment (Rails 5.2.4.3)
irb(main):001:0> Post.all.count
(4.5ms) SELECT COUNT(*) FROM "posts"
=> 1
データが生成されたのがわかりますね!
##課題
しかしcronの起動は手動で毎回行うのは面倒なので、できればdockerfileに記述して自動で起動されるようにしたいところです。
今後その方法も追記していきたと思います。