docker-composeのコンテナ内でcronを動かす
nginx+rails+PostgreSQLなアプリをdocker-composeで作っていた。
railsのアプリケーションでcronで実行したいrakeタスクがあった。
このタスクのcron化自体はrails(ruby)のgemで行うのだけど、うまく行かなかった。
原因としては、そのgemも結局は、railsアプリ内ではなくそれがのっているホスト(この場合はコンテナ)のcronの仕組みを使うためのラッパーのようなものなので、そもそもコンテナでcronが使えなきゃしょうがない。
結局調べてみたところ、rubyのimageはdebianがベースイメージとして使われていて、そのベースイメージではcronはなかった。
なので、apt-get installして使える必要にしてから、rails側でもcron化するgemを使用すべきなのだけど、面倒くさかったので強硬策に出ていた次第だ。
その方法とは、コンテナのホストから、コンテナごとcronで起動してしまう方法。
これでなんとか凌いでいたのだが、問題が発生。
ホストからcronのためだけにいちいちコンテナを起動して、終わったらそのままにしていたので、使い終わったコンテナがたくさん溜まっていくという現象が発生してしまった。
あくる日容量エラーになってしまったのだった。。。
これは良くないと思い、ちゃんとcronを使っていく。
まずは、動作確認のために、コンテナ上においてcronをinstallして使えるかどうか試してみる。
docker-compose.ymlはこんな感じ。 railsのコンテナでcronを使いたいので、以下のコマンドでシェルに接続で(言葉あってるのか?)
$ docker-compose run app bash
まずはcronをinstallする
# apt-get install cron
install成功したので、早速使ってみる。
# crontab -e no crontab for root - using an empty one update-alternatives: error: no alternatives for editor /usr/bin/sensible-editor: 25: /usr/bin/sensible-editor: editor: not found /usr/bin/sensible-editor: 28: /usr/bin/sensible-editor: nano: not found /usr/bin/sensible-editor: 31: /usr/bin/sensible-editor: nano-tiny: not found /usr/bin/sensible-editor: 34: /usr/bin/sensible-editor: vi: not found Couldn't find an editor! Set the $EDITOR environment variable to your desired editor. crontab: "/usr/bin/sensible-editor" exited with status 1
おっと、editorがない。そんなことがあるもんなんだな。 サクッとインスコしてみる。 適当にそれっぽいコマンドを想像して叩く。
# apt-get install vim
インスコできました。
1 * * * * echo hoge >> /var/log/cron/echo
と書いて保存。
しかし、そもそも/var/log/cronというディレクトリがなかった。
mkdir /var/log/cron
作ってみるも、なしのつぶて。 誰が悪いのか。
と、単に自分のcronがうんこだっただけだった。 以下のcronで。
* * * * * echo "Hello $(date)" >>/var/log/cron.log 2>&1
いやしかし、これも動かない。
どうやらcrontab -e
に問題がありそうだ。
/etc/crontab
を編集
以下を追加
* * * * * echo "Hello $(date)" >>/var/log/cron.log 2>&1
これもだめ、そもそもcronのサービスが起動していないんじゃないか。
それを調べよう。
redhut系で言うところのserviceはdebianでいうなんだっけか。
と思い調べ、結局わからず
# service cron status
と適当に売ってみたら、
[FAIL] cron is not running ... failed!
と表示された。
なんだdebianもserviceで良かったのか。
startさせます。
# service cron start [ ok ] Starting periodic command scheduler: cron.
よっしゃ成功! 1分待ってcronの実行を確認します。
実行されていました。
くぅ〜これにて完了です。
と言いたいところだが、これをdocker-compose.ymmlに書く。
としたいが、タイムオーバーで、これは明日にやることにする
ここまではローカルのdocker環境で実行していたので、これか本番で一旦cronをコンテナー内に仕込む
そして明日Dockerfileを変更する