为啥Dockerfile中的cron服务不运行?

Posted

技术标签:

【中文标题】为啥Dockerfile中的cron服务不运行?【英文标题】:Why doesn't the cron service in Dockerfile run?为什么Dockerfile中的cron服务不运行? 【发布时间】:2015-08-05 16:26:45 【问题描述】:

虽然searching 针对这个问题我发现:cron -f 应该启动服务。

所以我有:RUN apt-get install -qq -y git cron

接下来我有:CMD cron -f && crontab -l > pullCron && echo "* * * * * git -C $HOMEDIR pull" >> pullCron && crontab pullCron && rm pullCron

我的 dockerfile 部署没有错误,但 cron 没有运行。怎么做才能启动 cron 服务加上一行?

PS: 我知道我的 cron 中的 git 函数实际上应该是一个钩子,但对我(可能对其他人)来说,这是关于学习如何使用 Docker 设置 crons :-)

PPS: 完整的 Dockerfile(更新):

RUN apt-get update && apt-get upgrade -y
RUN mkdir -p /var/log/supervisor
RUN apt-get install -qq -y nginx git supervisor cron wget
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
RUN wget -O ./supervisord.conf https://raw.githubusercontent.com/..../supervisord.conf
RUN mv ./supervisord.conf /etc/supervisor/conf.d/supervisord.conf
RUN apt-get install software-properties-common -y && apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0x5a16e7281be7a449 && add-apt-repository 'deb http://dl.hhvm.com/ubuntu utopic main' && apt-get update && apt-get install hhvm -y
RUN cd $HOMEDIR && git clone $GITDIR && mv ./tybalt/* ./ && rm -r ./tybalt && git init
RUN echo "* * * * * 'cd $HOMEDIR && /usr/bin/git pull origin master'" >> pullCron && crontab pullCron && rm pullCron
EXPOSE 80
CMD ["/usr/bin/supervisord"]

购买力平价: Supervisord.conf:

[supervisord]
autostart=true
autorestart=true
nodaemon=true

[program:nginx]
command=/usr/sbin/nginx -c /etc/nginx/nginx.conf

[program:cron]
command = cron -f -L 15
autostart=true
autorestart=true

【问题讨论】:

复制到:***.com/questions/20545554/… 嗨@Armand,我确实找到了这个答案,但我不明白它是如何重复的?这实际上是让我添加cron -f 添加CMD 结尾的问题,但这似乎没有运行 Docker 使用单个进程启动实例。您能否详细说明您使用哪个命令启动实例?我学到的是,如果您需要运行更多进程,您应该考虑从命令行运行 supervisor,并让它负责启用您希望可用的系统进程。 @Armand 请看我的更新 嗯,我很抱歉我的重复消息,cron -f 确实应该工作。运行“docker logs CONTAINER”时你会得到什么?我很好奇 cron 是否在 syslog 中写了一些东西。 【参考方案1】:

已经用主管启动了 crond,你的 cron 作业应该被执行了。以下是您可以采取的故障排除步骤,以确保 cron 正在运行

    cron 守护进程是否在容器中运行?登录到容器并运行ps a | grep cron 进行查找。使用docker exec -ti CONTAINERID /bin/bash登录容器。

    supervisord 正在运行吗?

    例如,在我的设置中,以下主管配置可以正常工作。图片是ubuntu:14.04。我在 Dockerfile 中有 CMD ["/usr/bin/supervisord"]
[supervisord]
 nodaemon=true
[program:crond]
 command = /usr/sbin/cron
 user = root
 autostart = true

    尝试另一个简单的 cron 作业,以确定问题是您的 cron 条目还是 cron 守护程序。使用crontab -e 登录到容器时添加此内容:

    * * * * * echo "hi there" >> /tmp/test

    查看容器日志以获取有关 cron 的更多信息:

    docker logs CONTAINERID | grep -i cron

这些只是您可以遵循的一些故障排除提示。

【讨论】:

【参考方案2】:

Cron 没有运行,因为只有最后一个 CMD 覆盖了第一个(正如 @xuhdev 所说)。它记录在这里:https://docs.docker.com/reference/builder/#cmd。

一个 Dockerfile 中只能有一个 CMD 指令。如果你列出了多个 CMD,那么只有最后一个 CMD 会生效。

如果您想让nginxcron 在同一个容器中运行,您将需要使用某种类型的主管(如supervisord 或其他)作为pid 1 容器进程并管理子进程。我认为这个项目应该会有所帮助:https://github.com/nbraquart/docker-nginx-php5-cron(它似乎可以实现您想要实现的目标)。

根据你的 cron 在这里的用途,会有其他解决方案——比如为每个提交或每个标签构建一个新图像,等等......

【讨论】:

谢谢,我会检查一下并尽快返回结果。 我已经用 supervisord 更新了我的 dockerfile,它部署得很好,但是 cron 没有运行,有什么想法吗? (请参阅我有问题的更新 PPS)谢谢 可能取决于您的supervisord的配置/内容(并且supervisord必须在前台运行,带有-n标志) 已将其添加到我的 PPPS 中,还将我的 CMD ["/usr/bin/supervisord"] 更新为 CMD ["/usr/bin/supervisord", "-n"]【参考方案3】:

我已经在 CentOS 上使用过它并且它可以工作:

CMD service crond start ; tail -f /var/log/cron

我的 Dockerfile 的其余部分只是 yum 安装 cronie 并触及 /var/log/cron 文件,因此当 CMD 运行时它就会在那里。

【讨论】:

【参考方案4】:

在 centos 7 上这对我有用

[program:cron]
command=/usr/sbin/crond -n -s
user = root
autostart = true
stderr_logfile=/var/log/cron.err.log
stdout_logfile=/var/log/cron.log

-n 用于前景 -s 是记录到stdout和stderr

【讨论】:

【参考方案5】:

在我的例子中,我需要在运行时运行cron start。我不能把它放在我的 Dockerfile 和 docker-compose.yml 中,所以我最终把它放在了我用于部署的 Makefile 中。

类似:

task-name:
     @ docker-compose down && docker-compose build && docker-compose up -d
     docker exec CONTAINERNAME /bin/bash -c cron start

【讨论】:

以上是关于为啥Dockerfile中的cron服务不运行?的主要内容,如果未能解决你的问题,请参考以下文章

cron 作业未在 ubuntu 上的 docker 容器内运行

高山图像中的 Crontab [重复]

为啥我的 sidekiq 计划的 cron 作业没有在 heroku 上运行?

如何在 Docker 容器中以非 root 用户身份启动 cron?

Docker容器crontab未运行[重复]

为啥我的 dockerfile 中的 dotnet restore 步骤失败?