我试图在调用shell脚本的docker容器内运行cronjob。
昨天我一直在网上搜索,堆栈溢出,但我真的找不到一个有效的解决方案。 我该怎么做呢?
我试图在调用shell脚本的docker容器内运行cronjob。
昨天我一直在网上搜索,堆栈溢出,但我真的找不到一个有效的解决方案。 我该怎么做呢?
当前回答
如果你在windows上使用docker,请记住,如果你打算将crontab文件从windows导入到ubuntu容器中,你必须将行结束格式从CRLF更改为LF(即从dos更改为unix)。如果不是,你的工作就不会起作用。下面是一个工作示例:
FROM ubuntu:latest
RUN apt-get update && apt-get -y install cron
RUN apt-get update && apt-get install -y dos2unix
# Add crontab file (from your windows host) to the cron directory
ADD cron/hello-cron /etc/cron.d/hello-cron
# Change line ending format to LF
RUN dos2unix /etc/cron.d/hello-cron
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/hello-cron
# Apply cron job
RUN crontab /etc/cron.d/hello-cron
# Create the log file to be able to run tail
RUN touch /var/log/hello-cron.log
# Run the command on container startup
CMD cron && tail -f /var/log/hello-cron.log
这实际上花了我几个小时才弄清楚,因为在docker容器中调试cron作业是一项乏味的任务。希望它能帮助那些不能让他们的代码工作的人!
但是:如果cron死亡,容器将继续运行。
其他回答
您可以将crontab复制到映像中,以便从映像中启动的容器运行作业。
重要提示:docker-cron问题3中提到:cron文件使用LF,而不是CRLF。
参见Julien Boulay在他的Ekito/ Docker -cron中的“Run a cron job with Docker”:
让我们创建一个名为“hello-cron”的新文件来描述我们的工作。
# must be ended with a new line "LF" (Unix) and not "CRLF" (Windows)
* * * * * echo "Hello world" >> /var/log/cron.log 2>&1
# An empty line is required at the end of this file for a valid cron file.
如果你想知道什么是2>&1,Ayman Hourieh解释道。
下面的Dockerfile描述了构建映像的所有步骤
FROM ubuntu:latest
MAINTAINER docker@ekito.fr
RUN apt-get update && apt-get -y install cron
# Copy hello-cron file to the cron.d directory
COPY hello-cron /etc/cron.d/hello-cron
# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/hello-cron
# Apply cron job
RUN crontab /etc/cron.d/hello-cron
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Run the command on container startup
CMD cron && tail -f /var/log/cron.log
但是:如果cron死亡,容器将继续运行。
(见Gaafar的评论和我如何使apt-get安装噪音更小?: Apt-get -y install -qq——force-yes cron也可以工作)
正如Nathan Lloyd在评论中所指出的:
关于一个问题的简单说明: 如果您正在添加一个脚本文件并告诉cron运行它,请记住这样做 运行chmod 0744 /the_script 如果你忘记了,Cron会默默地失败。
或者,确保你的作业本身直接重定向到stdout/stderr,而不是一个日志文件,如hugoShaka的回答所述:
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
将最后一行Dockerfile替换为
CMD ["cron", "-f"]
但是:如果你想以非根用户的身份运行任务,它就不起作用了。
参见(关于cron -f,这是说cron“前景”)“docker ubuntu cron -f不能正常工作”
构建并运行它:
sudo docker build --rm -t ekito/cron-example .
sudo docker run -t -i ekito/cron-example
耐心等待2分钟,你的命令行应该显示:
Hello world
Hello world
Eric在评论中补充道:
请注意,如果tail是在映像构建期间创建的,那么它可能不会显示正确的文件。 如果是这种情况,您需要在容器运行时创建或触摸该文件,以便tail获得正确的文件。
参见“docker CMD末尾的tail -f输出不显示”。
更多信息请参见Jason Kulatunga的“在Docker中运行Cron”(2021年4月),他在下面评论道
参见Jason的图片AnalogJ/docker-cron基于:
Dockerfile安装cronie/crond,取决于发行版。 一个入口点初始化/etc/environment,然后调用 Cron -f -l 2
我根据其他答案创建了一个Docker映像,可以像这样使用
docker run -v "/path/to/cron:/etc/cron.d/crontab" gaafar/cron
/path/to/cron: crontab文件的绝对路径,或者你可以在Dockerfile中使用它作为基础文件:
FROM gaafar/cron
# COPY crontab file in the cron directory
COPY crontab /etc/cron.d/crontab
# Add your commands here
作为参考,图片在这里。
所以,我的问题也一样。修复方法是改变docker-compose.yml中的命令部分。
From
命令:crontab /etc/crontab && tail -f /etc/crontab
To
命令:crontab /etc/crontab
命令:tail -f /etc/crontab
问题在于命令之间的“&&”。删除后,一切都好了。
从上面的例子中,我创建了这样的组合:
在Nano中使用Crontab编辑高山图像(我讨厌vi)
FROM alpine
RUN apk update
RUN apk add curl nano
ENV EDITOR=/usr/bin/nano
# start crond with log level 8 in foreground, output to stderr
CMD ["crond", "-f", "-d", "8"]
# Shell Access
# docker exec -it <CONTAINERID> /bin/sh
# Example Cron Entry
# crontab -e
# * * * * * echo hello > /proc/1/fd/1 2>/proc/1/fd/2
# DATE/TIME WILL BE IN UTC
只要添加到答案列表中,你也可以使用这张图片: 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