2019/12/30SHAREツイートシェアはてブGoogle+PocketLINEこんばんはエンジニアの眠れない夜です。django-uwsgi-nginxをベースにcronを実行する方法です。これからDjangoで開発を始めるという方はdjango-uwsgi-nginx-cronを作ったのでこちらをクローンして開発を始めるととてもスムーズに進められます。https://github.com/sleepless-se/django-uwsgi-nginx-cronGitHubからクローンを作成し、その中のappフォルダの中にDjangoのプロジェクトを作成しています。(この辺は本家と同じです。一気に起動してくれるのでとても重宝しています。)cronを実行しようとDockerfileの中でいろいろやってみたのですがなかなかうまくいかなかったのでdjango-uwsgi-nginx-cronを作成しました。その中で、cronが起動するとNginxが起動しなくなり、Nginxが起動するとcronが起動するというあっちを立てればこっちが立たず。みたいな状況になりました。最終的にsupervisor-app.confを編集すればいいんだ!ということに気づいたのでその紹介です。標準ではこの様になっています。/usr/sbin/nginxここにcronを追加します。-fautostart=trueautorestart=truestdout_logfile=/var/log/supervisor/%(program_name)s.logstdout_logfile=/dev/stdoutstdout_logfile_maxbytes=0まずはこれを保存します。続いてcronの定義と実行ファイルを用意します。ここで注意が必要なのがコンテナの環境変数をcronでは引き継ぎません。コンテナの環境変数を書き出して、cron実行時に読み込ませる必要があります。/bin/bashでコンテナに入ります。下記のコードを実行します。/root/env.sh表示したら、内容をコピーします。PYTHONPATH=/usr/bin/python3↑こちらに書いているコードはもう少しいろいろ表示されるのですが、コンテナを起動するたびに変わる環境変数があるので読み込んでもエラーになります。私は不要だったので削除しました。必要なのはこれだけのはず。他にも必要なものがあれば各自追加してください。保存先はローカルのPCで、下記のようにcronフォルダを作ってその中にenv.shというファイルを作って保存します。環境変数のとり方はこちらの記事を参考にさせていただきました。cronファイルを用意するcronフォルダの中にcrontabというファイルを作って、その中にcronを書いていきます。crontabの最後には必ず改行を1行入れましょう。これがないとcronでインポートしたときにエラーが出ます。/home/docker/code/cron/env.shで先程保存した環境変数を読み込んでいます。これがないとパスが通っていないのでcronを実行してもpythonやdjangoが動かない。.はsourceと同意です。&&の後に実行したいコマンドを書きます。ここでは環境変数がきちんと読み込まれているかを確認するためにexportを実行しています。最後に、そのログを出力すると行った感じです。DockerにcronをインストールするDockerファイルのCMDの直前あたりに下記のコマンドを追記します。/home/docker/code/cron/crontab大事なのは初めの1行と最後の2行です。1行目でcronをインストールしています。最後から2行目でcronフォルダ直下の先ほど作成したファイルに実行権限を与えています。実行権限を与え忘れて、「あれ?動かない..?」ってよくなるやつです。(私だけでしょうか?)最後の1行はcronを読み込んでいます。これだけでもいいのですが、cronを利用するということはタイムゾーンの設定が必要なのでTZとかLANGの設定を追加しています。これがないと、標準時でcronが実行されたり、日本語を含むファイルを実行したときに文字コードでエラーになったりして苦しみます。django-uwsgi-nginxを使ったことがない方はReadmeをご確認ください。djangoのモデルなどを使ったスクリプトを作る場合はカスタムコマンドを作ってそれをcronから呼び出すといいです。現在は『アイデアをカタチにする』ことが仕事です。CommentDockerでDjangoのカスタムコマンドを実行すると複数回実行された話。