巨人の足元でたじlog

そうして言葉を軽んじるから――― 君は私の言葉を聞き逃す

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を変更する