我尝试在Docker容器内运行cron作业,但都无法正常工作。
我的容器只有cron.daily
和cron.weekly
文件。
crontab、cron.d、cron.hourly
在我的容器中不存在。
crontab -e
也不起作用。
我的容器使用的是/bin/bash
。
以下是我如何运行我的cron容器。
Dockerfile:
FROM alpine:3.3
ADD crontab.txt /crontab.txt
ADD script.sh /script.sh
COPY entry.sh /entry.sh
RUN chmod 755 /script.sh /entry.sh
RUN /usr/bin/crontab /crontab.txt
CMD ["/entry.sh"]
crontab.txt
*/30 * * * * /script.sh >> /var/log/script.log
entry.sh
#!/bin/sh
# start cron
/usr/sbin/crond -f -l 8
script.sh
#!/bin/sh
# code goes here.
echo "This is a script, run by cron!"
docker build -t mycron .
这样运行
docker run -d mycron
添加自己的脚本并编辑crontab.txt,然后构建镜像并运行。由于基于alpine,因此镜像非常小。
RUN apk add --update apk-cron && rm -rf /var/cache/apk/*
以提供完整示例。有很多种方法可以将 cron 添加到 Alpine 中,而这个方法是适用于您的示例的一种方法。 - Fmstratcrond 与 tiny 在 Alpine 上良好配合。
RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["/usr/sbin/crond", "-f"]
但不应作为容器的主进程(PID 1)运行,因为存在僵尸进程回收问题和信号处理问题。请参见此 Docker PR和此博客文章获取详细信息。
@ken-cochrane的解决方案可能是最好的,但也有一种方法可以在不需要创建额外文件的情况下完成。
做法是在entrypoint.sh
文件中设置cron。
Dockerfile
...
# Your Dockerfile above
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh
echo "* * * * * echo 'I love running my crons'" >> /etc/crontabs/root
crond -l 2 -f > /dev/stdout 2> /dev/stderr &
# You can put the rest of your entrypoint.sh below this line
...
#!/bin/ash
。 - Daniel Mirandadcron
和 Alpine Linux:
docker-compose.yml
:services:
dcron:
build: .
command: crond -fl info
init: yes
Dockerfile
:
FROM alpine:3.17
RUN set -x \
&& apk add --no-cache dcron shadow \
&& useradd -m app
COPY crontab /etc/crontabs/app
crontab
:
* * * * * date >/dev/null 2>&1
在我的gist中可以找到更多信息。
我在这里让它在非root用户下运行任务,因为你不应该给予比所需权限更高的权限(最小特权原则),即使是在docker
容器内部也是如此。
这种解决方案的缺点是你无法在docker logs
中看到任务的输出。这就是为什么我建议你尝试一下适用于docker
的cron
实现,例如supercronic
:
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 .
crontab
:
* * * * * date
Docker文件示例:
FROM alpine
# Copy script which should be run
COPY ./myawesomescript /usr/local/bin/myawesomescript
# Run the cron every minute
RUN echo '* * * * * /usr/local/bin/myawesomescript' > /etc/crontabs/root
CMD ['crond', '-l 2', '-f']
/etc/crontabs/root
所做的更改并不存在。 - JesusIniesta