Dockerでcrondをフォアグラウンド起動しておく

dockerでcrondをフォアグラウンド起動しておくメモ。

crontabのことは以前に書いたけれども、dockerでcrondを使用することについては、あまり細かいことを書いていなかったので、別で書いておきたい。

crontabのメモ
crontabでのあれこれ 更新履歴 2022/12: Dockerでのcronの使用に関する記事のリンクを追加 基本はmanを見る ここを見ると大抵のことは解決できると思います。 上のページを見て、この場合はどうなるんだろう、といったケー...

更新履歴

  • 2022/12: 見出しの整理。githubのサンプルレポジトリを追加。

やりたいこと

docker上でcrondを動作させたい。できればrootでないユーザ上で起動させたい。正直rootでも問題はなさそうだけどユーザについてのメモも残したいので記録しておく。

外部からの入力・リクエストを受け付けるならrootでないほうがいい。

crontabファイルについては省略。テスト用では* * * * * echo -n hello crontab && dateだけ書いている。

実際使うならverboseになる-lやcrondのログの出力先を決める-Lオプションは変更する。

docker composeで使っており、docker-compose.ymlは次のようなごく単純なもの:

services:
  cron:
    build: .

この前提でdockerでcrondを使用したい。

USER設定するとそのままでは動かない

crondはrootでの動作が前提になっているようで、次のように:

# ./BadDockerfile
## うまくいかない例
FROM python:alpine

ARG ANUSER=myuser

COPY crontabfile /tmp/crontabfile
RUN adduser -D ${ANUSER} && \
    crontab -u ${ANUSER} /tmp/crontabfile && \
    rm /tmp/crontabfile

USER ${ANUSER}

CMD [ "crond", "-f", "-l", "0", "-L", "/dev/stdout" ]

ただUSERを設定しただけでは、起動はするものの、permission deniedになっていて定期実行されない。

rootで動かす

なお、rootのままでいいならば、USER設定を省いた以下で十分動く:

# ./Dockerfile1
## このようにrootで動かせば普通に動く。
FROM python:alpine

COPY crontabfile /tmp/crontabfile
RUN crontab /tmp/crontabfile && \
    rm /tmp/crontabfile

CMD [ "crond", "-f", "-l", "0", "-L", "/dev/stdout" ]

ユーザを変更して動かすならsudoersを編集する

ちょうどsudoersについていじっていたので、これに追加すればいいとすぐに思いついた。ただ、Alpineにはsudoコマンドがないので、apkでの導入が必要になる。

そして、特定ユーザの特定コマンドの実行でパスワードの要求を不要にすればいいので、次のようになる:

# ./Dockerfile2
FROM python:alpine

ARG ANUSER=myuser

COPY crontabfile /tmp/crontabfile
RUN apk update --no-cache && \
    apk add --no-cache sudo && \
    adduser -D ${ANUSER} && \
    echo "Cmnd_Alias USERCOMMANDS = /usr/sbin/crond" >> /etc/sudoers && \
    echo "${ANUSER} ALL=PASSWD: ALL, NOPASSWD: USERCOMMANDS" >> /etc/sudoers && \
    crontab -u ${ANUSER} /tmp/crontabfile && \
    rm /tmp/crontabfile

USER ${ANUSER}

CMD [ "sudo", "crond", "-f", "-L", "/dev/stdout" ]

これで目的は達成できた。

githubにサンプルを用意した(2022/12追記)

crondwhoamiするだけのサンプルレポジトリを用意した。docker-compose.ymlを書き換えてビルド時に使用するDockerfileを切り替えてユーザの変化を確認できる:

GitHub - ikapper/foreground-crond-docker
Contribute to ikapper/foreground-crond-docker development by creating an account on GitHub.

おわり

ほかにも、supervisordを使う方法もある。以前に書いた。

dockerとsupervisordでcronを追加で動かす
docker上で動くdjangoアプリのバッチ処理をsupervisordとcronで行う。 背景 今までにもバッチ処理に関する記事は書いていましたが、今回はdocker+supervisord+cronの組み合わせでdjangoのmana...

よく考えて使い分けたい。ほかの方法もあるだろう。

ひとまず、docker+crondについては以上です。

タイトルとURLをコピーしました