Dockerコンテナ内でcronジョブを実行する
コンテナ内で実行環境を構築する場合、スクリプトを定期的に動かすために、コンテナ内で cron を起動します。
Dockerfile に cron のインストールを追加します。
RUN apt update && apt install -y cron
docker-compose.yml で environment
に PYTHONPATH などの環境変数を指定します。
environment:
- PYTHONPATH=$${PYTHONPATH}:/home/user/modules
Python 側でサーバを起動する際に、subprocess.Popen() で cron を起動します:
subprocess.Popen(['cron', '-f'])
そして、定期実行のスクリプトに引数を追加し、実行対象となるシェルスクリプトを生成して、ジョブを登録します。
注意すべきなのは、環境変数 PYTHONPATH を設定し、Python インタプリタのフルパスを指定する必要があります。
import os
import subprocess
from pathlib import Path
from argparse import ArgumentParser
if __name__ == '__main__':
parser = ArgumentParser()
parser.add_argument('--cron', action="store_true")
args = parser.parse_args()
if args.cron:
py_path = os.environ.get('PYTHONPATH')
fp = Path(__file__).absolute()
content = (
'#!/bin/bash\n'
f'export PYTHONPATH={py_path}\n'
f'/root/miniconda3/bin/python {str(fp)}'
' > /root/cron.log 2>&1'
)
sh_fp = Path.home() / 'my_script.sh'
with open(sh_fp, 'w') as sh:
sh.write(content)
# ジョブをCronに登録
cmd = (f'crontab -l | {{ cat; echo "0 12 * * * /bin/bash {sh_fp}"; }}'
' | crontab -')
subprocess.run(cmd, shell=True)