Dockerfile

Dockerfile

nginx我在docker中使用。我已配置cron作业来更新 SSL 证书和 DNS 注册。但是,cron作业没有运行。

我做了什么。我创建了一个Dockerfile基于arm32v7/nginx这个实习生的基础debian:stretch-slim。起初我安装了cron,并假设它会运行,但后来发现该服务没有启动(没有安装 init 子系统, debian:stretch-slim 非常小)。所以我添加了代码来启动cron。现在,如果我询问容器是否cron正在运行,它会说是。

#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

答案1

我安装是rsyslog为了看看我遇到了什么错误,我得到了以下信息

(*system*) NUMBER OF HARD LINKS > 1 (/etc/crontab)。一些搜索告诉我,cron如果有大量指向其文件的硬链接,则安全策略将不起作用。不幸的是,Docker 的分层文件系统使文件具有大量硬链接。

为了解决这个问题,我touch /etc/crontab /etc/cron.*/*在运行之前将 , 添加到启动脚本中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— 如果未安装
  • 添加 cron 作业/etc/cron.daily/(或每周)。确保您的脚本名称仅包含字母、数字、连字符、没有点。 (别问)看cron 作业未从 cron.daily 运行
  • 将 s 配置文件的硬链接计数cron减少到 1:do touch /etc/crontab /etc/cron.*/*—(如果在 docker 中)。我把它放在启动脚本中。
  • 开始cron: service cron start— (如果在基本操作系统上,没有 init。就像在 docker 中使用的许多基本映像一样)。我把它放在启动脚本中。

此答案中的入口点脚本以及问题中的其他所有内容都会执行此操作。当前项目可以通过以下方式获取hg clone ssh://[email protected]/davids_dad/a_website

相关内容