您好,我正在尝试在 docker 容器中运行 cron 作业。所以我在我的Dockerfile
我的Dockerfile
FROM nginx:stable
RUN apt-get update -y && apt-get upgrade -y && apt-get install -y \
vim \
git \
curl \
wget \
certbot \
cron
COPY cron/crontab /etc/crontab
RUN chmod 0644 /etc/cron.d/crontab
RUN /etc/init.d/cron start
我的crontab
档案
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
*/1 * * * * root echo "test" >>~/readme
但这不起作用。
如果我希望它工作,我必须/etc/init.d/cron start
在 nginx 容器中手动运行该命令。
所以我在 my 中添加了一个入口点Dockerfile
,这样这个命令就可以在容器启动时执行。
# ENTRYPOINT
ADD entrypoint.sh /entrypoint.sh
RUN chmod 777 /entrypoint.sh
我的entrypoint.sh
#!/usr/bin/env bash
/etc/init.d/cron start
我的docker-compose
entrypoint: /entrypoint.sh
但我有这个错误:
OCI 运行时执行失败:执行失败:container_linux.go:296: 启动容器进程导致“process_linux.go:86: 执行 setns 进程导致\“退出状态 21\””:未知
我错过了什么?
PS:我已经关注了这个教程
答案1
几天前,我正在努力解决类似的问题,这里有一些基于我首先学到的知识的注释:
为了能够像服务一样运行容器,某个地方(在 cmd 或入口点)必须有一个正在运行的前台程序。对于你的情况,它是
nginx -g daemon off;
(来自 nginx 图像)。此外,如果有入口点和 cmd,它们将以 cmd 作为参数传递给入口点的方式启动(就像
./entrypoint.sh [cmd]
)没有任何意义,
RUN /etc/init.d/cron start
因为在构建镜像之后,它无论如何都会被终止。
解决方案:它正在使用入口点.sh与此类似(在我的例子中是 django/gunicorn/cron):
#!/bin/bash
set -e # exit on any error
if [ "$1" = './gunicorn.sh' ]; then # './gunicorn.sh' is default command
cron # this runs cron as daemon
crontab -u django /app/crontab # this applies a crontab from a file
exec su django -c "$@" # this actually runs the default command as different user (you can just use exec "$@" if you dont need to run it as different user)
fi
exec "$@" # this runs any other cmd without starting cron (e.g. docker run -ti myimage /bin/bash)
答案2
您使用什么作为 Docker 映像的基础(即FROM
行中的内容)?
许多 docker 基础镜像都是从现有发行版(例如 alpine、debian、ubuntu、centos 等)的最小安装开始,然后向其中添加所需的任何软件包。
如果默认情况下不包含您的基础映像cron
,请使用发行版适当的打包工具(例如)将其安装在 Dockerfile 中apt-get install cron
,然后像在任何其他系统上一样配置它 - 例如,通过向系统 crontab 文件添加一个条目,例如/etc/crontab
,或者通过将可执行脚本放入/etc/cron.d
.
在某些情况下,cron
可能已安装但被禁用。您需要修改容器的启动脚本以使其启动crond
。这与在 Dockerfile 中使用 RUN 命令不同(用于在容器构建过程中运行命令,而不是在每个容器启动时运行命令)。具体操作方法因您使用的基础映像而异。