docker 容器中的 crontab

docker 容器中的 crontab

您好,我正在尝试在 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 命令不同(用于在容器构建过程中运行命令,而不是在每个容器启动时运行命令)。具体操作方法因您使用的基础映像而异。

相关内容