序文として、私はこれら2つの記事を参照して助けを求めてきました。
私の目標は、Dockerコンテナを起動すると、cronジョブが自動的に開始されるようにすることです。現在、自動的に起動しませんが、手動でコンテナに移動してservice cron start
、これはジョブを開始し、正常に動作します。
だから問題は:コンテナの起動時にcronジョブを自動的に起動するにはどうすればいいですか?
Dockerfile
FROM Microsoft/dotnet:latest
RUN apt-get update && apt-get install -y cron
COPY . /app
WORKDIR /app
ADD crontab /etc/cron.d/crontab
RUN chmod 0600 /etc/cron.d/crontab
RUN crontab -u root /etc/cron.d/crontab
RUN touch /var/log/cron.log
RUN ["dotnet", "restore"]
RUN ["dotnet", "build"]
EXPOSE 5000/tcp
CMD cron && tail -f /var/log/cron.log
CMD service cron start
crontab
* * * * * echo "Hello world" >> /var/log/cron.log 2>&1
# Empty space
その特定のコンテナーでcronを動作させることはできませんでしたが、cron専用のスタンドアロンDockerコンテナーを作成することができ、自動的に実行することに成功しました。
Cronコンテナのセットアップに関しては、リンクされた記事 Dockerでcronジョブを実行する-Julien Boulay に従って、機能させることができました。
私がやっていることは、次のようにCMDを直接cronに呼び出すことです:
CMD /usr/sbin/cron -f
その前に、私はcrontabをコンテナに追加し、コマンドでルートcrontabとして割り当てます:
RUN crontab /root/mycrontab
/etc/cron.d
にあるファイルに対してcrontabコマンドを呼び出す必要はありませんが、それらのファイルに正しい構文が必要です。これの代わりに例を使用して:
* * * * * echo "Hello world" >> /var/log/cron.log 2>&1
これが必要です:
* * * * * root echo "Hello world" >> /var/log/cron.log 2>&1
Crontabファイル上。これは、/etc/cron.d
内にあるcrontabファイルにのみ適用されます。そうでない場合、crontabファイルの構文は正しいので、crontab
コマンドを使用してロードします。
あなたの例から始めて、私はあなたがこのようにファイルを修正するべきだと思います:
Dockerfile
FROM Microsoft/dotnet:latest
RUN apt-get update && apt-get install -y cron
COPY . /app
WORKDIR /app
ADD crontab /etc/cron.d/crontab
RUN chmod 0600 /etc/cron.d/crontab
RUN touch /var/log/cron.log
RUN ["dotnet", "restore"]
RUN ["dotnet", "build"]
EXPOSE 5000/tcp
CMD /usr/sbin/cron -f
crontab
* * * * * root echo "Hello world" >> /var/log/cron.log 2>&1
別の選択肢は次のとおりです。
Dockerfile
FROM Microsoft/dotnet:latest
RUN apt-get update && apt-get install -y cron
COPY . /app
WORKDIR /app
ADD crontab /root/
RUN crontab /root/crontab
RUN touch /var/log/cron.log
RUN ["dotnet", "restore"]
RUN ["dotnet", "build"]
EXPOSE 5000/tcp
CMD /usr/sbin/cron -f
crontab
* * * * * echo "Hello world" >> /var/log/cron.log 2>&1
Debianベースのディストリビューションには、Dockerが階層化ファイルシステムを使用し、cronが起動せずNUMBER OF HARD LINKS > 1 (/etc/crontab)
と表示するため、cronjobが失敗するバグがあります。
修正は簡単です。touch /etc/crontab /etc/cron.*/*
コンテナのエントリポイントへ。
ここでDockerコンテナにcronをセットアップする方法を説明するブログ投稿を作成しました: https://digitz.org/blog/cron-jobs-in-docker/
php-fpmとdockerで問題が発生し、cronjobタスクが実行されませんでした。解決した問題は2つありました。
COPY config/custom-cron /etc/cron.d/custom-cron
を使用して、crontab
ファイルをdockerコンテナーにコピーしようとしました。問題は、行末がwindows形式であったことです。これにより、crontabファイルが破損しました。この行のendigは、そのファイルをコンテナにコピーしている間は変換されないためです。CMD ["cron", "-f"]
プロセスをブロックしたphp-fpm
を介してcronを起動しようとしたことです。これにより、Webアプリケーションを呼び出すときに502 Bad gateway
エラーが発生します。最後に、コピーアンドペーストの代わりにdockerイメージを構築し、supervisordを使用してDocker内で複数のタスクを実行することで、crontabファイルを手動で編集することで機能させました。これは、サポートされているすべてのオペレーティングシステムで動作するはずです。
FROM php:7.1.16-fpm
RUN apt-get update && apt-get install -y cron supervisor
# Configure cron
RUN crontab -l | { cat; echo "* * * * * echo 'Hello world' >> /var/log/cron-test.log 2>&1"; } | crontab -
# Configure supervisor
COPY config/supervisord.conf /etc/supervisor/supervisord.conf
[supervisord]
logfile = /dev/null
loglevel = info
pidfile = /var/run/supervisord.pid
nodaemon = true
[program:php-fpm]
command = php-fpm
autostart = true
autorestart = true
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0
[program:cron]
command = cron -f
autostart = true
autorestart = true
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0
これは古い質問ですが、Debianでこれを修正し、問題を解決しました。 uidを使用したcron pam authにより、cronが実行できなくなりました。
RUN sed -i '/session required pam_loginuid.so/c\#session required pam_loginuid.so/' /etc/pam.d/cron