【问题标题】:Cron isn't running when I start my docker container当我启动我的 docker 容器时,Cron 没有运行
【发布时间】:2017-03-03 23:34:30
【问题描述】:

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

我的目标是在我启动 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 进行操作,并且能够使其正常工作。

【问题讨论】:

  • 您是否需要在容器内运行 cron,或者您是否可以在主机上创建一个 cron 作业以在所需时间运行此容器以完成其工作?
  • @R0MANARMY 它需要在容器内运行。
  • 你已经看过this question
  • @R0MANARMY 是的,这个问题基本上只是概述了我的第一个参考。
  • 根据Docker docs,Dockerfile 中只能有一条 CMD 指令。我建议取出第二个。看起来您的 Dockerfile 与另一个答案中的差异只有几个。我会尝试一次更改那些,看看你是否可以让它运行。

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


【解决方案1】:

我正在做的是让 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

【讨论】:

  • 感谢您的回复!我很难跟踪你。您介意编辑您的答案以显示我的 Dockerfilecrontab 文件的样子吗?谢谢!
  • 我尝试了您的两个版本的答案,但仍然无法正常工作。我可以提供任何其他信息来提供更好的帮助吗?
  • 我刚刚使用第二个版本(从 dockerfile 中删除了 dotnet restore 和 build 命令)对其进行了测试,并且 cron 可以正常工作。你能进入容器里面看看 cron 是否正在运行吗? (例如:ps auxw|grep cron
  • 所以我正在做的是; docker-compose builddocker-compose up -d,然后我通过docker exec -it {container-id} bash进入我的容器,然后通过service cron status检查cron是否正在运行,返回cron is not running ... failed!
  • 我尝试使用相同的命令,但对我来说service cron status 返回cron is running.。我正在使用 4.4.0.45 通用内核的 ubuntu 机器上进行测试。您是在 Windows 机器上进行测试吗?
【解决方案2】:

我们遇到了 php-fpm 和 docker 问题,无法执行我们的 cronjob 任务。我们解决了两个问题:

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

最后,我们通过手动编辑 crontab 文件来实现它,同时构建 docker 映像而不是复制粘贴,并使用 supervisord 在 docker 内运行多个任务。这应该适用于所有受支持的操作系统。

码头文件

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

【讨论】:

  • 非常感谢您指出这一点!我们注意到,我们的 laravel 计划作业突然停止在 PROD 应用程序中工作,并且不知道为什么。事实证明,这个问题是在我们部署了一个在 Windows 上构建的 docker 容器之后开始的。以前我们只部署了基于 Linux 构建的容器。我刚刚将 crontab 转换为 UNIX 格式并且能够解决这个问题,即使是从 Windows 机器上部署的。再次感谢!
【解决方案3】:

基于 Debian 的发行版中存在一个错误,这将导致 cronjobs 失败,因为 docker 使用分层文件系统并且 cron 无法启动并显示 NUMBER OF HARD LINKS > 1 (/etc/crontab)

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

我在这里发表了一篇博文,解释如何在 Docker 容器中设置 cron:https://esc.sh/blog/cron-jobs-in-docker/

【讨论】:

  • 仅供参考:您博客的证书似乎已过期。无法通过 Safari 访问。
  • 非常感谢伙计。我已经更改了域名。修复它:)
【解决方案4】:

我知道这是一个老问题,但我在 Debian 上找到了解决这个问题的方法,它解决了我的问题。带有 uid 的 Cron pam auth 使我的 cron 无法运行。

RUN sed -i '/session    required     pam_loginuid.so/c\#session    required     pam_loginuid.so/' /etc/pam.d/cron

【讨论】:

    猜你喜欢
    • 2021-08-15
    • 1970-01-01
    • 2023-03-21
    • 2020-02-07
    • 2022-01-14
    • 1970-01-01
    • 2014-11-20
    • 1970-01-01
    • 2017-11-18
    相关资源
    最近更新 更多