はじめに
Linuxでコマンドを定期的に自動実行するにはcronというものを使うとよいらしい。
しかし、Dockerコンテナ内でPythonをcronをしようとすると意外と大変だったのでメモ。
Dockerコンテナの立ち上げ
Dockerの解説は、さくらのナレッジの解説がわかりやすくておすすめです。
さて、まずは適当な場所で以下のようなディレクトリを作ります。
test/
├ docker-compose.yml
└ Dockerfile
ファイルの中身はそれぞれ、
version: '3'
services:
main:
build:
context: .
dockerfile: Dockerfile
container_name: test
volumes:
- ./:/workspace
stdin_open: true
tty: true
ports:
- "127.0.0.1:8000:8888"
FROM python:3.8
RUN apt update
です。基本的なことしか書いていません。
testフォルダの中で以下のコマンドを打ち、コンテナを作って中に入りましょう。
docker-compose up -d
docker-compose exec main bash
用意したファイルはworkspaceフォルダにあります。
順番に試す
まず、このままだとcronを設定するために必要なコマンドcrontab -e
が動きません。
root@34cf5a4ef1fd:/# crontab -e
bash: crontab: command not found
cronをインストールしてやる必要があるようなので以下のコマンドでインストールします。
apt-get install -y cron
もう一回crontab -e
を打つと、今度はエディターがないと怒られます。
root@34cf5a4ef1fd:/# crontab -e
no crontab for root - using an empty one
update-alternatives: error: no alternatives for editor
/usr/bin/sensible-editor: 25: editor: not found
/usr/bin/sensible-editor: 28: nano: not found
/usr/bin/sensible-editor: 31: nano-tiny: not found
/usr/bin/sensible-editor: 34: vi: not found
Couldn't find an editor!
Set the $EDITOR environment variable to your desired editor.
crontab: "/usr/bin/sensible-editor" exited with status 1
以下のコマンドでとりあえずvimをインストールします。
apt-get install -y vim
これでcrontab -e
が動くようになったので、とりあえずシェルスクリプトを1分ごとに動かしてみます。
テスト用に、/workspaceに以下のシェルスクリプトを用意します。
#!/bin/bash
echo "hello" >> /workspace/hello.txt
helloという文字列をテキストファイルに追記していくスクリプトです。
次に、crontab -e
コマンドで設定ファイルを編集して、以下の分を追記します。
これがcronの設定になります。
*/1 * * * * /workspace/test.sh
1分ごとにシェルスクリプトを実行してくださいという設定です。
パスはフルパスで設定します。
そして、以下のコマンドでcronの定期実行をスタートさせます。
/etc/init.d/cron start
うまく動いていれば、hello.txtが作成され、1分ごとにhelloという文字列が追加されていきます。
止めるときは、
/etc/init.d/cron stop
です。
次にPythonコマンドを動かしてみたいので、/workspaceに.pyファイルを作成します。
with open('/workspace/hello.txt', 'a') as f:
print('python', file=f)
同じようにpythonという文字列をhello.txtに追記していくプログラムです。
同じようにcrontab -e
でcronの設定をしたいのですが、以下の記述だと動きません。
*/1 * * * * python /workspace/test.py
cronがPythonのパスを認識してくれないことが原因のようです。
そこで、which python
コマンドでpythonファイルの場所を見つけ出して、そこのパスをコマンドとして、以下のように書き直します。
*/1 * * * * /usr/local/bin/python /workspace/test.py
これで動くようになります。
参考にした記事
- https://haitech-blog.com/cron-path/
- https://qastack.jp/ubuntu/262063/how-to-find-python-installation-directory-on-ubuntu
- https://qiita.com/sey323/items/407cfa303f9ec217c677
- https://teratail.com/questions/281244
- https://qiita.com/yasuaki0206/items/306c859f0854dd0cfabf
- https://qiita.com/nagimaruxxx/items/b7308644b5d2c9efbeea
- https://qiita.com/houtarou/items/cad584e7d10adf22e417
- https://ytyaru.hatenablog.com/entry/2020/05/25/000000