当我启动docker容器时,Cron没有运行

时间:2016-10-21 15:22:31

标签: docker asp.net-core cron docker-compose

作为序言,我一直在参考这两篇文章寻求帮助:

我的目标是在启动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容器的设置而言,我遵循了链接的文章Run a cron job with Docker - Julien Boulay,并且能够使其正常运行。

4 个答案:

答案 0 :(得分:9)

我正在做的是直接使用CMD调用cron:

CMD /usr/sbin/cron -f

在此之前,我将crontab添加到容器中,并使用以下命令将其指定为root 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

答案 1 :(得分:2)

基于Debian的发行版中存在一个错误会导致cronjobs失败,因为docker使用分层文件系统而cron没有启动并说NUMBER OF HARD LINKS > 1 (/etc/crontab)

修复很简单,将touch /etc/crontab /etc/cron.*/*添加到容器的入口点。

我发了一篇博客文章,解释了如何在Docker容器中设置cron:https://digitz.org/blog/cron-jobs-in-docker/

答案 2 :(得分:0)

我们在 php-fpm 和docker上遇到了问题,其中cronjob任务未执行。我们解决了两个问题:

  • 我们尝试使用crontabCOPY config/custom-cron /etc/cron.d/custom-cron文件复制到docker容器中。问题是,我们的行结尾 windows 格式。这确实破坏了我们的crontab文件,因为在将该文件复制到容器中时不会转换该行尾标。
  • 第二个问题是,我们试图通过CMD ["cron", "-f"]启动cron,但确实阻塞了主要的php-fpm进程。调用我们的Web应用程序时,这会导致502 Bad gateway错误。

最后,我们通过在构建docker映像时手动编辑crontab文件(而不是复制粘贴)并使用超级用户使docker内部运行多个任务来使其工作。这应该在所有受支持的操作系统上都有效。

dockerfile

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.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

答案 3 :(得分: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