在 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)。
您可以编写自己的 CMD
或 ENTRYPOINT
脚本来启动 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。
我从 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)。
您可以编写自己的
CMD
或ENTRYPOINT
脚本来启动 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。