在Docker容器中,cronjobs没有得到执行

我从Dockerfile中创build了一个Docker镜像,并且当基于这个镜像的容器正在运行时,我想定期执行一个cronjob。 我的Dockerfile是这个(相关部分):

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"] 

创build图像后,我运行一个容器,并确认cronjob确实已经添加:

 crontab -l */2 * * * * node /srv/visitor/visitor.js 

现在,问题是cronjob永远不会被执行。 当然,当我从控制台手动运行时,我testing了“node /srv/visitor/visitor.js”执行正确。

有任何想法吗?

回答这个问题确实有点棘手,因为我没有时间去testing,但是你可以有多种select:

  • 您可以使用Phusion基本映像,该映像随安装的init系统和cron一起提供。 它基于Ubuntu并且相对比较重量级(至less与archlinux相比) https://registry.hub.docker.com/u/phusion/baseimage/

  • 如果你很高兴从cron作业开始,那么你可以从你的CMD开始执行cron,并保留在前台( cron -f )。

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

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

就你而言,如果你只是在玩游戏,我会select最后一个选项,如果更严重的话,我会和一个stream程pipe理者一起去。

一种select是按照以下方式使用主机的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循环,而不是编写和调用shell脚本来执行相同的操作。 所以它非常灵活。

或者你也可以把复杂的脚本放在docker容器中,像下面这样运行它们:

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

如果你正在用–net = host运行你的Docker容器,请看这个线程: https : //github.com/docker/docker/issues/5899

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