Dockerでnginx
を使用しています。 SSL証明書とDNS登録を更新するようにcron
ジョブを構成しました。ただし、cron
ジョブは実行されていません。
私が何をした。 arm32v7/nginx
に基づいてDockerfile
を作成しました。このインターンはdebian:stretch-slim
に基づいています。最初にcron
をインストールして実行すると想定しましたが、サービスが開始されていないことがわかりました(initサブシステムがインストールされていないため、debian:stretch-slimは非常に最小限です)。そこで、cron
を開始するコードを追加しました。 cron
が実行されているかどうかをコンテナに尋ねると、yesと表示されます。
#ctrl-alt-delor@raspberrypi:~/a_website/docker$
#↳ docker exec -it $(docker container ls | sed -nr -e 's/.*(website-stack.*)/\1/p') service cron status
[ ok ] cron is running.
ただし、cron
に追加したタスクのログは表示されません。
run-parts --report /etc/cron.daily
を実行すると、私のタスクが実行され、ログ出力が生成されます。そのため、cron
が実行されていないように見えます。
#ctrl-alt-delor@raspberrypi:~/a_website/docker$
#↳ docker exec -it $(docker container ls | sed -nr -e 's/.*(website-stack.*)/\1/p') cat /proc/12/cmdline; echo
/usr/sbin/cron
つまり、cron
がジョブを実行していないのはなぜですか?何を逃したのですか?
Dockerfile
FROM arm32v7/nginx
##add backports
COPY stretch-backports-source.list /etc/apt/sources.list.d/
##install cron and curl — so we can register dns regularly
RUN apt-get update &&\
apt-get install -y cron curl &&\
apt-get clean
##setup cron to register dns
COPY register-dns register-dns.auth register-dns-hostname /usr/local/bin/
COPY register-dns.cron /etc/cron.daily/1-register-dns
RUN chmod +x /usr/local/bin/register-dns /etc/cron.daily/1-register-dns
##add curtbot
RUN apt-get update && \
apt-get -t stretch-backports install -y python-certbot-nginx && \
apt-get clean
#add ssl port
EXPOSE 443 80
##custom entry point — needed by cron
COPY entrypoint /entrypoint
RUN chmod +x /entrypoint
ENTRYPOINT ["/entrypoint"]
CMD ["nginx", "-g", "daemon off;"] #:tricky: we seem to need to re-specify this
LABEL name="my-nginx" \
description="nginx + cron + curl + certbot + dns-registering"
entrypoint
#!/bin/sh
## Do whatever you need with env vars here ...
service cron start
# Hand off to the CMD
exec "$@"
/etc/crontab
Shell=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
/etc/cron.daily/1-register-dns
#!/bin/sh
date >> /var/log/register-dns
/usr/local/bin/register-dns >>/var/log/register-dns
rsyslog
をインストールして、どのエラーが発生しているかを確認しました。
(*system*) NUMBER OF HARD LINKS > 1 (/etc/crontab)
。少し検索したところ、cron
には、ファイルへのハードリンクが多数ある場合は機能しないというセキュリティポリシーがあることがわかりました。残念ながら、Dockerの階層化ファイルシステムは、ファイルに多数のハードリンクを作成します。
これを修正するために、cron
を実行する前に、起動スクリプトにtouch /etc/crontab /etc/cron.*/*
を追加しました。これにより、他のファイルインスタンスからの接続が解除されます。
新しいエントリポイントは
#!/bin/sh
#fix link-count, as cron is being a pain, and docker is making hardlink count >0 (very high)
touch /etc/crontab /etc/cron.*/*
service cron start
# Hand off to the CMD
exec "$@"
私はテストし、それは動作します
cron
を動作させるには、必要があります。
cron
—インストールされていない場合/etc/cron.daily/
(または毎週)に追加します。スクリプト名に文字、数字、ハイフンのみが含まれていることを確認しますドットなし。 (質問しないでください)参照 cronジョブがcron.dailyから実行されていないcron
s構成ファイルのハードリンク数を1に減らします:do touch /etc/crontab /etc/cron.*/*
—(dockerの場合)。起動スクリプトに入れました。cron
:service cron start
—(基本OSの場合、初期化なし。Dockerで使用する多くの基本イメージと同様)起動スクリプトに入れました。この回答のエントリポイントスクリプトと、質問のその他すべてがそれを実行します。現在のプロジェクトはhg clone ssh://[email protected]/davids_dad/a_website
で取得できます