如何在 docker 容器中运行 cron 作业

Posted

技术标签:

【中文标题】如何在 docker 容器中运行 cron 作业【英文标题】:How to run a cron job inside a docker container 【发布时间】:2016-08-29 04:14:50 【问题描述】:

我尝试在 docker 容器中运行 cron 作业,但对我没有任何作用。 我的容器只有 cron.dailycron.weekly 文件。crontab,cron.d,cron.hourly 在我的容器中不存在。crontab -e 也不起作用。 我的容器使用/bin/bash 运行。

【问题讨论】:

【参考方案1】:

这是我运行我的一个 cron 容器的方法。

Dockerfile:

FROM alpine:3.3

ADD crontab.txt /crontab.txt
ADD script.sh /script.sh
COPY entry.sh /entry.sh
RUN chmod 755 /script.sh /entry.sh
RUN /usr/bin/crontab /crontab.txt

CMD ["/entry.sh"]

crontab.txt

*/30 * * * * /script.sh >> /var/log/script.log

entry.sh

#!/bin/sh

# start cron
/usr/sbin/crond -f -l 8

script.sh

#!/bin/sh

# code goes here.
echo "This is a script, run by cron!"

像这样构建

docker build -t mycron .

这样跑

docker run -d mycron

添加您自己的脚本并编辑 crontab.txt,然后构建映像并运行。由于是基于alpine,所以图片超级小。

【讨论】:

这很棒。我遇到的一个问题是,在 docker run ... 我无法使用 ctrl-c 停止容器运行?即使在我关闭终端之后,当我执行 docker ps 时,我也可以看到容器仍在运行。有人有同样的问题吗? 请在答案中添加RUN apk add --update apk-cron && rm -rf /var/cache/apk/* 以获取完整示例。列出的将 cron 添加到 alpine 的方法有很多,而这一种方法适用于您的示例。 嗨,为什么有 2 个 ADD 和 1 个 COPY?,根据我读到的内容,3 COPY 或 3 ADD 可以正常工作(在这种情况下)。我说的对吗? crond -f -l 8, 8 是什么意思?据 man 说,日志级别是大写的L 我没有看到 crond 默认在容器中运行。我必须执行并运行 crond,这实际上触发了 cron 作业。我在这里缺少什么吗?【参考方案2】:

crond 与 Alpine 上的 tiny 配合得很好

RUN apk add --no-cache tini

ENTRYPOINT ["/sbin/tini", "--"]
CMD ["/usr/sbin/crond", "-f"]

但不应作为容器主进程 (PID 1) 运行,因为僵尸收割问题和信号处理问题。详情请参阅this Docker PR 和this blog post。

【讨论】:

为什么不应该作为PID1运行?【参考方案3】:

Here is good explanation of cron problems inside docker container:

Docker 文件示例:

FROM alpine

# Copy script which should be run
COPY ./myawesomescript /usr/local/bin/myawesomescript
# Run the cron every minute
RUN echo '*  *  *  *  *    /usr/local/bin/myawesomescript' > /etc/crontabs/root

CMD ['crond', '-l 2', '-f']

【讨论】:

就我而言,这种方法行不通。我也尝试了一些变体,似乎在最终容器中,对/etc/crontabs/root 所做的更改不存在。【参考方案4】:

@ken-cochrane 的解决方案可能是最好的,但是,还有一种方法可以做到这一点,而无需创建额外的文件。

无需额外文件即可:

要走的路是在 entrypoint.sh 文件中设置 cron。

Dockerfile


...

# Your Dockerfile above


COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

entrypoint.sh


echo "* * * * * echo 'I love running my crons'" >> /etc/crontabs/root
crond -l 2 -f > /dev/stdout 2> /dev/stderr &

# You can put the rest of your entrypoint.sh below this line

...

【讨论】:

以上是关于如何在 docker 容器中运行 cron 作业的主要内容,如果未能解决你的问题,请参考以下文章

在我在docker容器中重新保存cron文件之前,Cron作业不起作用

如何使用Docker将NodeJS应用程序与cron作业进行容器化?

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

在 docker 中运行 cron python 作业

Docker 并行运行 cron 作业

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