我试图在调用shell脚本的docker容器内运行cronjob。

昨天我一直在网上搜索,堆栈溢出,但我真的找不到一个有效的解决方案。 我该怎么做呢?


当前回答

对于那些想要使用简单和轻量级图像的人:

FROM alpine:3.6

# copy crontabs for root user
COPY config/cronjobs /etc/crontabs/root

# start crond with log level 8 in foreground, output to stderr
CMD ["crond", "-f", "-d", "8"]

其中cronjobs是包含cronjobs的文件,格式如下:

* * * * * echo "hello stackoverflow" >> /test_file 2>&1
# remember to end this file with an empty new line

但显然你不会在docker日志中看到hello stackoverflow。

其他回答

我想分享一些我发现更灵活的其他建议的典型的修改。我想用一个环境变量来启用更改cron时间,最后添加了一个额外的脚本,在我的entrypoint.sh中运行,但在调用cron -f之前

*updatecron.sh*
#!/bin/sh
#remove old cron files
rm -rf /etc/cron.*/*
#create a new formatted cron definition
echo "$crondef [appname] >/proc/1/fd/1 2>/proc/1/fd/2" >> /etc/cron.d/restart-cron
echo \ >> /etc/cron.d/restart-cron
chmod 0644 /etc/cron.d/restart-cron
crontab /etc/cron.d/restart-cron

这将删除任何现有的cron文件,使用crondef的ENV变量创建一个新的cronfile,然后加载它。

我偶尔尝试寻找一个docker友好的cron实现。最后一次尝试,我找到了一对。

我所说的对docker友好的意思是,“任务的输出可以在docker日志中看到,而不是诉诸于技巧。”

目前我认为最有希望的是超级克隆。它可以提供一个crontab文件,同时对docker友好。利用它:

docker-compose.yml:

services:
  supercronic:
    build: .
    command: supercronic crontab

Dockerfile:

FROM alpine:3.17
RUN set -x \
    && apk add --no-cache supercronic shadow \
    && useradd -m app
USER app
COPY crontab .

定时任务:

* * * * * date

有更多信息的要点。

另一个不错的是yacron,但它使用YAML。

可以使用Ofelia,但它们似乎专注于在单独的容器中运行任务。这可能不是一个缺点,但我不确定为什么我想这么做。

还有一些传统的cron实现:dcron, fcron, cronie。但它们“没有简单的方法来查看任务的输出”。

VonC的回答相当彻底。此外,我想补充一件对我有帮助的事情。如果您只想运行一个cron作业而不跟踪文件,那么您可能会想从cron命令中删除&& tail -f /var/log/cron.log。

然而,这将导致Docker容器在运行后不久退出,因为当cron命令完成时,Docker认为上一个命令已经退出,因此杀死了容器。这可以通过在前台通过cron -f运行cron来避免。

还有另一种方法,就是使用Tasker,它是一种支持cron(调度器)的任务运行器。

为什么?有时为了运行cron作业,你必须将你的基本映像(python, java, nodejs, ruby)与crond混合。这意味着要维持另一个形象。Tasker通过解耦crond和you容器来避免这种情况。您可以只关注想要执行命令的映像,并配置Tasker来使用它。

这里是船坞式作曲。Yml文件,它将为您运行一些任务

version: "2"

services:
    tasker:
        image: strm/tasker
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
        environment:
            configuration: |
                logging:
                    level:
                        ROOT: WARN
                        org.springframework.web: WARN
                        sh.strm: DEBUG
                schedule:
                    - every: minute
                      task: hello
                    - every: minute
                      task: helloFromPython
                    - every: minute
                      task: helloFromNode
                tasks:
                    docker:
                        - name: hello
                          image: debian:jessie
                          script:
                              - echo Hello world from Tasker
                        - name: helloFromPython
                          image: python:3-slim
                          script:
                              - python -c 'print("Hello world from python")'
                        - name: helloFromNode
                          image: node:8
                          script:
                              - node -e 'console.log("Hello from node")'

这里有3个任务,它们都将每分钟运行一次(every: minute),并且每个任务都将在image section中定义的图像中执行脚本代码。

只要运行docker-compose up,就能看到它在工作。以下是Tasker回购的完整文档:

http://github.com/opsxcq/tasker

虽然这旨在通过Docker的exec接口在容器中运行进程的旁边运行作业,但您可能会感兴趣。

我已经编写了一个守护进程,用于观察容器并调度在其元数据中定义的作业。例子:

version: '2'

services:
  wordpress:
    image: wordpress
  mysql:
    image: mariadb
    volumes:
      - ./database_dumps:/dumps
    labels:
      deck-chores.dump.command: sh -c "mysqldump --all-databases > /dumps/dump-$$(date -Idate)"
      deck-chores.dump.interval: daily

“经典”,cron一样的配置也是可能的。

这是文档,这是图像存储库。