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

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


当前回答

当在一些限制根访问的经过修剪的映像上运行时,我必须将我的用户添加到sudoers并作为sudo cron运行

FROM node:8.6.0
RUN apt-get update && apt-get install -y cron sudo

COPY crontab /etc/cron.d/my-cron
RUN chmod 0644 /etc/cron.d/my-cron
RUN touch /var/log/cron.log

# Allow node user to start cron daemon with sudo
RUN echo 'node ALL=NOPASSWD: /usr/sbin/cron' >>/etc/sudoers

ENTRYPOINT sudo cron && tail -f /var/log/cron.log

也许这对某人有帮助

但是:如果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友好的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。但它们“没有简单的方法来查看任务的输出”。

虽然这旨在通过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一样的配置也是可能的。

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

只要添加到答案列表中,你也可以使用这张图片: https://hub.docker.com/repository/docker/cronit/simple-cron

并使用它作为启动cron作业的基础,像这样使用它:

FROM cronit/simple-cron # Inherit from the base image
#Set up all your dependencies 
COPY jobs.cron ./ # Copy your local config

所以,我的问题也一样。修复方法是改变docker-compose.yml中的命令部分。

From

命令:crontab /etc/crontab && tail -f /etc/crontab

To

命令:crontab /etc/crontab

命令:tail -f /etc/crontab

问题在于命令之间的“&&”。删除后,一切都好了。