Dockerコンテナで定期的(分次、時次、日次、週次、月次など)で実行したいときに、
Cronは有効な解決方法です。
この記事では、Dockerコンテナ(Compose)でDjangoコマンドを環境変数込みで定期実行する方法をまとめました。
目次
Dockerコンテナで"環境変数込みで"Cronを実行するには?
DockerコンテナでCronを実行するには以下の2パターンがあると思います。
ここではポータビリティを重視するため、前者の「コンテナにCronを実装する方法」を採用して説明します。
コンテナ内のCronで実行する方法
Dockerコンテナ内のcronでは、ホストPCからコンテナ内に注入された環境変数が反映されないため、
いろいろと工夫する必要があります。[1]
※crontabに直接Djangoコマンドを入力した場合、「KeyError:」となってしまいます。詳しくは「補足 crontabに直接Djangoコマンドを入力した場合」にまとめています。
そのため、「実行スクリプト(runCronProcess.sh)」と「環境変数リスト化スクリプト(initEnv.sh)」、「環境変数設定スクリプト(env.sh)」の3つのスクリプトで実装します。
DockerFileに追記する
以下の処理をDockerfileに追記します。
・COPYするinitEnv.shとrunCronProcess.shのディレクトリやファイル名はご自分の環境に合わせて変更してください。
・赤色下線のところが本命の処理(1分間隔で呼び出されるようにしています)です。
スクリプトを記述する
・「. /root/env.sh
」の下にcronで実行させたい処理を追加していきます。
・Djangoの格納場所やコマンドはご自分の環境に合わせて変更してください。上の例では/codeにDjangoのsrcがあるような設定となっています。
docker-compose.ymlで環境変数リスト化スクリプトの実行処理を追加
・Djangoを起動する前に、initEnv.shの処理を追加します。なお、上の例ではDjangoを起動するためにuwsgiを実行する想定としています。
実行してみる
以下のコマンドを実行してDockerコンテナを再起動します。
起動時のDockerコンテナのログを(docker logs
等で)確認すると、
「initEnv.sh」が実行されていることが分かります。
cronの結果はコンテナ内の/log/test.logに出力しています。
中身を確認すると以下のように、Djangoコマンドが1分間隔で実行されているはずです。
補足 crontabに直接Djangoコマンドを入力した場合
crontabに直接Djangoコマンドを入力した場合、DjangoにホストPCの環境変数が注入されないため、エラーとなってしまいます。
参考
[1] Docker コンテナ内でタスクを cron 起動する
[2] Docker コンテナ内で cron を実行し実行ログを出力する方法
以上!
コメント