Docker×Djangoで Cron を設定する方法

docker Django cron

こんばんは、エンジニアの眠れない夜です。

以前ご紹介したDjangoを https 化した状態でデプロイできるDockerコンテナを使ってCronを設定する方法を紹介します。

このリポジトリを利用しない場合でも supervisor を使ってCronを設定する方法と同じなのでDjangoを利用しているか否かにかかわらず他のプロジェクトにも応用可能です。

記事全体にDjango的要素は無いのですが、利用しているリポジトリがDjango用なのでこのようなタイトルにしました。

Docker+DjangoでCronを実行!設定概要

DockerでCronを実行するまでのステップは大きく分けて3つのステップに分かれています。

  1. cron実行用ファイルを準備
  2. DockerfIleを編集
  3. supervisor-app.confを編集

個人的にはcron実行用ファイルを準備するところで環境変数を書き出すところがDockerでcronを実行するポイントだと思います。

それでは順番に見ていましょう。

cron実行用ファイルを準備

今回は django-uwsgi-nginx/django-uwsgi-nginx 直下に作成します。同じフォルダ名が続いていて分かりづらいのですが、appフォルダがある階層です。ここにcronフォルダを作ります。

この中に3つのファイルを用意します。

Docker+Djangoで Cron を設定する方法

crontab cronの設定内容を書きます。
env.sh Docker内の環境変数を書き出したものです。
read_mail.sh cronから呼び出されるシェルスクリプトです。ファイル名は自由に設定して大丈夫です。crontabファイル内に直接記述しても良いのですが、長くなりそうなので別ファイルにしました。(この辺はお好みにあわせて。)

crontab cronの設定内容

普通にcronファイルを書けば大丈夫です。今回はシェルスクリプトに内容をまとめたいのでシェルスクリプトを参照しています。


# m h dom mon dow user	command
* * * * * /code/cron/read_mail.sh
シェルファイルははDocker内の/code/cron/にあとでコピーします。

env.sh Docker内の環境変数を書き出す方法

Docker内の環境変数はビルドするときと実行するときでは引き継がれないようです。環境変数をファイルに書き出して、Cron実行前に読み込む。という面倒なことが必要です。

Docker内にdocker exec -it コンテナID /bin/bash で入ります。その後に下記のコードを実行します。


printenv | awk '{print "export " $1}' > /root/env.sh
cat /root/env.sh

/root/env.sh の中身をcatで確認します。出てきた環境変数をコピーしてenv.shをcronフォルダの中に保存します。

毎回変化する環境変数も一緒に記述されているので私はこれだけに減らしました。


export TERM=xterm
export LC_ALL=en_US.UTF-8
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PWD=/root
export LANG=en_US.UTF-8
export TZ=Asia/Tokyo
export SHLVL=1
export HOME=/root
export LANGUAGE=en_US:en
export PYTHONPATH=/usr/bin/python3
export DEBCONF_NOWARNINGS=yes
export LESSOPEN=|
export LESSCLOSE=/usr/bin/lesspipe
export _=/usr/bin/printenv
export OLDPWD=/var/log

一般的な内容なのでこれをコピペするだけでも良いんじゃないかと思います。リポジトリを利用されている方は特に。

この辺り適当なので、もう少し詳しく知りたい方は下記のページをご参照ください。

https://qiita.com/rerofumi/items/fc0126c4e985b78f769b

read_mail.sh の内容

ポイントは先程作成したenv.shをコマンド実行前に読み込むことです。
※コマンドは適当です

Python

#!/bin/sh
. /code/cron/env.sh
/usr/bin/python3 /code/app/manage.py read_mail >> /var/log/read_mail 2>&1

2.DockerfIleを編集

下記のコードをDockerfileの最後の方、EXPOSEの上辺りにコピペします。


RUN apt-get install -y cron
RUN chmod 0744 /code/cron/*
RUN crontab /code/cron/crontab

やっていることはcronのインストールとCronフォルダ内のファイルに実行権限を与えて、cronを読み込んでいます。

/code/cron/*でいきなりどうしてそこにCronフォルダがあるの?と思う方もいるかも知れませんがリポジトリを利用している場合は70行目辺りで COPY . /code/でDocker内にコピーされています。

その他の方は COPY /path/to/cron_folder/ /code/ で、先程作成したCronフォルダを/code/の直下に保存してください。

3.supervisor-app.confを編集

最後にsupervisorの設定を行います。

django-uwsgi-nginx/django-uwsgi-nginx/supervisor-app.conf というファイルがあるのでこのファイルに下記のコードを最後に追加します。

[program:cron] command =cron -f
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0

リポジトリを利用している人はこれで設定完了です。それ以外の方はDockerfileに下記の2つの設定が必要です。



COPY path/to/supervisor-app.conf /etc/supervisor/conf.d/
CMD ["supervisord", "-n"]

上記の設定ファイルをDocker内にコピーしてスパーバイザーを起動しています。

最後に

こちらのリポジトリを利用されている方向けの内容とそうでない人向けに両方書いたら少しややこしい感じになってしまいました。

また、利用していない方向けには上記の説明だけでは足りないところもあるかもしれないので十分に説明書きしれず申し訳ないです。

うまくいかない所があればコメントか、Twitterで問い合わせをいただければ可能な限り返信加筆修正させていただきますm(_ _)m

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください