在 Docker 容器内,cronjobs 没有被执行

Inside Docker container, cronjobs are not getting executed

我从 Docker 文件制作了一个 Docker 图像,我希望在基于此图像的容器 运行ning 时定期执行 cronjob。我的 Docker 文件是这样的(相关部分):

FROM l3iggs/archlinux:latest

COPY source /srv/visitor

WORKDIR /srv/visitor

RUN pacman -Syyu --needed --noconfirm \
        && pacman -S --needed --noconfirm make gcc cronie python2 nodejs phantomjs \
        && printf "*/2 * * * *       node /srv/visitor/visitor.js \n" >> cronJobs \
        && crontab cronJobs \
        && rm cronJobs \
        && npm install -g node-gyp \
        && PYTHON=/usr/sbin/python2 && export PYTHON \
        && npm install

EXPOSE 80

CMD ["/bin/sh", "-c"]

创建图像后,我 运行 一个容器并验证是否确实添加了 cronjob:

crontab -l

*/2 * * * *     node /srv/visitor/visitor.js

现在,问题是 cronjob 永远不会执行。当然,我已经测试过 "node /srv/visitor/visitor.js" 在从控制台手动 运行 时正确执行。

有什么想法吗?

要明确回答这个问题有点棘手,因为我没有时间测试,但您有多种选择:

  • 您可以使用 Phusion 基础映像,它安装了 init 系统和 cron。它基于 Ubuntu 并且比较重量级(至少与 archlinux 相比) https://registry.hub.docker.com/u/phusion/baseimage/

  • 如果您乐于从 cron 作业开始一切,您可以从 CMD 启动 cron 并将其保留在前台 (cron -f)。

  • 你可以使用轻量级进程管理器来启动cron和你需要的任何其他进程(Phusion使用runit,Docker似乎推荐supervisor)。

  • 您可以编写自己的 CMDENTRYPOINT 脚本来启动 cron 和您的进程。唯一的问题是您需要小心地正确处理信号,否则您可能会遇到僵尸进程。

在你的情况下,如果你只是玩玩,我会选择最后一个选项,如果更严重,我会选择流程管理员。

一种选择是按以下方式使用主机的 crontab:

0 5 * * * docker exec mysql mysqldump --databases myDatabase -u myUsername -pmyPassword > /backups/myDatabase.sql

以上将定期对 MySQL 数据库进行每日备份。

如果您需要链接复杂的命令,您也可以使用这种格式:

0 5 * * * docker exec mysql sh -c 'mkdir -p /backups/`date +\%d` && for DB in myDB1 myDB2 myDB3; do mysqldump --databases $DB -u myUser -pmyPassword > /backups/`date +\%d`/$DB.sql; done'

上面对多个数据库进行了 30 天的滚动备份,并在一行中执行了 bash for 循环,而不是编写和调用 shell 脚本来执行相同的操作。所以它非常灵活。

或者您也可以将复杂的脚本放入 docker 容器中,然后 运行 它们像这样:

0 5 * * * docker exec mysql /dailyCron.sh

如果您 运行 使用 --net=host 连接您的 Docker 容器,请参阅此主题: https://github.com/docker/docker/issues/5899

我有同样的问题,当我在 docker 运行 命令行参数中包含 --pid=host 时,我的 cron 任务开始 运行ning。