我试图在调用shell脚本的docker容器内运行cronjob。
昨天我一直在网上搜索,堆栈溢出,但我真的找不到一个有效的解决方案。 我该怎么做呢?
我试图在调用shell脚本的docker容器内运行cronjob。
昨天我一直在网上搜索,堆栈溢出,但我真的找不到一个有效的解决方案。 我该怎么做呢?
当前回答
我们的是一个作为cron作业运行的nodejs应用程序,它也依赖于环境变量。
下面的解决方案适用于我们。
码头工人文件:
# syntax=docker/dockerfile:1
FROM node:12.18.1
ENV NODE_ENV=production
COPY ["startup.sh", "./"]
# Removed steps to build the node js application
#--------------- Setup cron ------------------
# Install Cron
RUN apt-get update
RUN apt-get -y install cron
# Run every day at 1AM
#/proc/1/fd/1 2>/proc/1/fd/2 is used to redirect cron logs to standard output and standard error
RUN (crontab -l ; echo "0 1 * * * /usr/local/bin/node /app/dist/index.js > /proc/1/fd/1 2>/proc/1/fd/2") | crontab
#--------------- Start Cron ------------------
# Grant execution rights
RUN chmod 755 startup.sh
CMD ["./startup.sh"]
startup.sh:
!/bin/bash
echo "Copying env variables to /etc/environment so that it is available for cron jobs"
printenv >> /etc/environment
echo "Starting cron"
cron -f
其他回答
所有的答案都需要容器内的根访问权限,因为'cron'本身请求UID 0。 请求根访问(例如通过sudo)是违反docker最佳实践的。 我使用https://github.com/gjcarneiro/yacron来管理计划任务。
@VonC的建议很好,但我更喜欢在一行中完成所有cron作业配置。这将避免像cronjob位置这样的跨平台问题,并且您不需要单独的cron文件。
FROM ubuntu:latest
# Install cron
RUN apt-get -y install cron
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Setup cron job
RUN (crontab -l ; echo "* * * * * echo "Hello world" >> /var/log/cron.log") | crontab
# Run the command on container startup
CMD cron && tail -f /var/log/cron.log
运行docker容器后,你可以通过以下方式确定cron服务是否在工作:
# To check if the job is scheduled
docker exec -ti <your-container-id> bash -c "crontab -l"
# To check if the cron service is running
docker exec -ti <your-container-id> bash -c "pgrep cron"
如果你喜欢用ENTRYPOINT代替CMD,那么你可以用
ENTRYPOINT cron start && tail -f /var/log/cron.log
但是:如果cron死亡,容器将继续运行。
下面是我的基于docker-compose的解决方案:
cron:
image: alpine:3.10
command: crond -f -d 8
depends_on:
- servicename
volumes:
- './conf/cron:/etc/crontabs/root:z'
restart: unless-stopped
带有cron条目的行在./conf/cron文件中。
注意:这将不会运行不在alpine映像中的命令。
此外,任务的输出显然不会出现在docker日志中。
这一行帮助我运行了预先计划好的任务。
ADD mycron/root /etc/cron.d/root
RUN chmod 0644 /etc/cron.d/root
RUN crontab /etc/cron.d/root
RUN touch /var/log/cron.log
CMD ( cron -f -l 8 & ) && apache2-foreground # <-- run cron
我的项目运行在:FROM php:7.2-apache
但是:如果cron死亡,容器将继续运行。
对于多个作业和各种依赖项(如zsh和curl),这是一种很好的方法,同时还结合了其他答案的最佳实践。额外的好处:这并不需要你在myScript.sh上设置+x个执行权限,这在新环境中很容易错过。
cron.dockerfile
FROM ubuntu:latest
# Install dependencies
RUN apt-get update && apt-get -y install \
cron \
zsh \
curl;
# Setup multiple jobs with zsh and redirect outputs to docker logs
RUN (echo "\
* * * * * zsh -c 'echo "Hello World"' 1> /proc/1/fd/1 2>/proc/1/fd/2 \n\
* * * * * zsh /myScript.sh 1> /proc/1/fd/1 2>/proc/1/fd/2 \n\
") | crontab
# Run cron in forground, so docker knows the task is running
CMD ["cron", "-f"]
将此与docker compose集成,如下所示:
docker-compose.yml
services:
cron:
build:
context: .
dockerfile: ./cron.dockerfile
volumes:
- ./myScript.sh:/myScript.sh
请记住,当您更改cron的内容时,您需要docker编写构建cron。但对myScript.sh的更改将在compose中挂载时立即反映出来。