本記事ではalpineを使用したDockerコンテナでcronによるジョブの定期実行を行う方法を説明します。
イメージの作成
まずはcronで実行されるスクリプトを書きます。
今回の例では、hello worldのメッセージと現在時刻を/var/log下にあるファイルへ追記しています。
#!/bin/sh
echo "hello world at $(date)" >> /var/log/cronlog.log
次に、このスクリプトを実行するcron定義を書きます
* * * * * /bin/sh /usr/local/bin/crontask.sh
上記の2つを含んだDockerコンテナを作るためのDockerfileを作ります。
下記の例ではタイムゾーンをJSTに変更していますが、UTCのままでよければ最初のRUNは不要です。
FROM alpine:3.9
# timezoneをJSTにする
RUN apk --update add tzdata && \
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
apk del tzdata && \
rm -rf /var/cache/apk/*
# cronのスクリプトをコピー
COPY crontask.sh /usr/local/bin
COPY crontab_root /var/spool/cron/crontabs/root
RUN chmod 644 /usr/local/bin/crontask.sh
# cronのdaemonを起動(log level=1, foreground)
CMD crond -l 1 -f
Dockerfileからimageを作成します。今回はコンテナの名前をexample/cron
としました。
$ docker image build -t example/cron .
コンテナの起動
下記のコマンドで、作成したexample/cronのイメージからコンテナを実行します。
$ docker container run -itd --name cron01 example/cron
動作の確認
cronで実行されるスクリプトは/var/log/cronlog.log
にログを書いていたので、下記のコマンドで結果を確認できます。
$ docker container exec -it cron01 tail /var/log/cronlog.log
hello world at Sat Mar 16 17:47:00 JST 2019
hello world at Sat Mar 16 17:48:00 JST 2019
hello world at Sat Mar 16 17:49:00 JST 2019
hello world at Sat Mar 16 17:50:00 JST 2019
...
また、crond自体の実行ログは、下記のコマンドで確認できます。
$ docker logs -f cron01
crond[1]: crond (busybox 1.29.3) started, log level 1
crond[1]: user:root entry:* * * * * /bin/sh /usr/local/bin/crontask.sh
crond[1]: user:root entry:* * * * * /bin/sh /usr/local/bin/crontask.sh
crond[1]: wakeup dt=60
crond[1]: file root:
crond[1]: line /bin/sh /usr/local/bin/crontask.sh
crond[1]: job: 0 /bin/sh /usr/local/bin/crontask.sh
crond[203]: child running /bin/ash
crond[1]: USER root pid 203 cmd /bin/sh /usr/local/bin/crontask.sh
...
コンテナ/イメージの削除
今回作ったdockerコンテナとイメージが必要なくなったら、下記のコマンドで全て削除できます。
$ docker container stop cron01
$ docker container rm cron01
$ docker image rm example/cron
こちらもおススメ