在 Docker 中,如何以编程方式(脚本)正确地将任务添加到 cron?日志中没有发现任何错误

在 Docker 中,如何以编程方式(脚本)正确地将任务添加到 cron?日志中没有发现任何错误

在与 Docker 捣鼓了几天之后,我还没有找到解决问题的方法。

简而言之,我尝试添加cronphp:8.1-apache-bullseye传递一个文件,其中包含我希望 cron 服务执行的任务:

cron-task内容:

* * * * * /var/www/html/Asset/resource/cron/cron.sh >> /var/log/cron/cron.log 2>&1

内容cron.sh

#!/bin/bash

# Get current time
current_time=$(date +"%H:%M:%S")

# Warning message
message="warning: Hello, world!!"

# Print time and message to stdout
echo "${current_time}: ${message}"

为了设置好一切,我在 docker-compose.yml 中设置了一个部分,在其中我设置了一个 web 服务器服务,如下所示:

  webserver:
    env_file:
      - .env
    container_name: ${LH_SYSTEM_NAME}-Web-Server
    build:
      context: ./bin/${LH_PHP_ENVIRONMENT}
    restart: always
    networks:
      - lamp-network
    depends_on:
      - database
    volumes:
      - ${LH_PROJECT_ROOT}:/var/www/html:rw
      - ${LH_PROJECT_ROOT}${LH_DOCUMENT_ROOT-./public}:/var/www/html/public:rw
      - ${LH_VHOSTS_DIR}:/etc/apache2/sites-enabled
      - ${LH_PHP_INI}:/usr/local/etc/php/php.ini
      - ${LH_CRON}:/etc/script/cron-task
      - ${LH_LOG_CRON}:/var/log/cron
      - ${LH_LOG_DIR}:/var/log/apache2
    environment:
      LH_WEB_MASTER: ${LH_WEB_MASTER}
      VIRTUAL_HOST: ${LH_WEB_SERVER_DOMAIN}
      LH_APACHE_DOCUMENT_ROOT: ${LH_APACHE_DOCUMENT_ROOT}
      LH_DOCUMENT_ROOT: ${LH_DOCUMENT_ROOT}
      HOST_MACHINE_MYSQL_PORT: ${LH_HOST_MACHINE_MYSQL_PORT}
      MYSQL_DATABASE: ${LH_MYSQL_DATABASE}
      MYSQL_ROOT_PASSWORD: ${LH_MYSQL_ROOT_PASSWORD}
      MYSQL_USER: ${LH_MYSQL_USER}
      MYSQL_PASSWORD: ${LH_MYSQL_PASSWORD}
    extra_hosts:
      - "host.docker.internal:host-gateway"
    command: [ "/bin/sh", "-c", "chmod +x /var/www/html/Asset/resource/cron/cron.sh && cp /etc/script/cron-task /etc/cron.d/cron-task && chmod 0644 /etc/cron.d/cron-task && crontab /etc/cron.d/cron-task && cron -f && service cron restart" ]

笔记:我们可以忽略环境变量,因为它们都经过了逐一测试和验证,并且执行了预期的操作......

此外,我正在实施该command部分以查看是否能解决问题,但从我所看到和测试的情况来看,它也不起作用。

在命令中执行的命令:

chmod +x /var/www/html/Asset/resource/cron/cron.sh
cp /etc/script/cron-task /etc/cron.d/cron-task
chmod 0644 /etc/cron.d/cron-task
crontab /etc/cron.d/cron-task
cron -f
service cron restart

这样容器内的文件就位于正确的位置...这一切都运行良好,即使在命令中执行的命令我在容器的构建和启动中也没有遇到任何中断或错误消息。

因此我的 Dockerfile 包含以下内容:

FROM php:8.1-apache-bullseye

ARG DEBIAN_FRONTEND=noninteractive

RUN a2enmod rewrite headers

RUN service apache2 restart

RUN apt-get update &&  \
    apt-get upgrade -y --no-install-recommends --fix-missing

RUN apt-get install -y cron nano wget dialog build-essential git curl zip openssl --no-install-recommends --fix-missing

RUN apt-get -y autoremove && \
    apt-get clean

ENV VISUAL=nano
ENV EDITOR=nano

RUN service cron start

RUN rm -rf /usr/src/* && \
    rm -rf /var/lib/apt/lists/*

RUN update-rc.d cron enable

这也不会给我带来任何问题...现在我转到我的 Web 服务器容器的终端,尽管我随后使用以下命令进行验证:

service cron status

输出表明它正在运行......

查看内容crontab -e

在此处输入图片描述

最终的问题是,什么都没有自动发生......就好像 cron 服务停止了一样......

为了以防万一,我在 .sh 文件上运行了测试,并且终端上的一切运行正常。

甚至将记录添加到日志中...但是当我等待 cron 服务执行此操作时,什么也没有发生......而且我不再知道该做什么或在哪里查找......

更新:

输出:ps aux | grep cron

曾是:

root 1 0.0 0.0 2480 516 ? Ss 21:46 0:00 /bin/sh -c chmod +x /var/www/html/Asset/resource/cron/cron.sh && cp /etc/script/cron-task /etc/cron.d/cron -task && chmod 0644 /etc/cron.d/cron-task && crontab /etc/cron.d/cron-task && cron -f && service cron restart
root 11 0.0 0.0 3744 2444 ? S 21:46 0:00 cron -f
root 78 0.0 0.0 3240 712 pts/0 S+ 22:11 0:00 grep cron

因此,尽管我尝试了所有方法,但似乎任务还没有在 cron 中......我仍然不知道该怎么办......

答案1

在尝试了不同的方法来操作文件并以适当的顺序创建需求以将 cron 实用程序集成到容器中并使其保持工作之后,这是必要的:

  1. 从我的 docker-compose.yml 文件中删除command一些参数/部分,现在它看起来像这样:volumenes
version: "3.8"

services:
  reverse-proxy:
    env_file:
      - .env
    container_name: Proxy-Server
    image: jwilder/nginx-proxy
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
    ports:
      - "${LH_HOST_MACHINE_UNSECURE_HOST_PORT}:80"
    depends_on:
      - webserver
      - phpmyadmin
    networks:
      - lamp-network
    extra_hosts:
      - "${LH_WEB_SERVER_DOMAIN}:127.0.0.1"
      - "${LH_PHPMYADMIN_DOMAIN}:127.0.0.1"
      - "${LH_CRON_DOMAIN}:127.0.0.1"
      - "${LH_INCRON_DOMAIN}:127.0.0.1"
  webserver:
    env_file:
      - .env
    container_name: ${LH_SYSTEM_NAME}-Web-Server
    build:
      context: ./bin/${LH_PHP_ENVIRONMENT}
    restart: always
    networks:
      - lamp-network
    depends_on:
      - database
    volumes:
      - ${LH_PROJECT_ROOT}:/var/www/html:rw
      - ${LH_PROJECT_ROOT}${LH_DOCUMENT_ROOT}:/var/www/html/public:rw
      - ${LH_VHOSTS_DIR}:/etc/apache2/sites-enabled
      - ${LH_PHP_INI}:/usr/local/etc/php/php.ini
      - ${LH_LOG_DIR}:/var/log/apache2
      - ${LH_LOG_CRON}:/var/log/cron
    environment:
      LH_WEB_MASTER: ${LH_WEB_MASTER}
      VIRTUAL_HOST: ${LH_WEB_SERVER_DOMAIN}
      LH_APACHE_DOCUMENT_ROOT: ${LH_APACHE_DOCUMENT_ROOT}
      LH_DOCUMENT_ROOT: ${LH_DOCUMENT_ROOT}
      HOST_MACHINE_MYSQL_PORT: ${LH_HOST_MACHINE_MYSQL_PORT}
      MYSQL_DATABASE: ${LH_MYSQL_DATABASE}
      MYSQL_ROOT_PASSWORD: ${LH_MYSQL_ROOT_PASSWORD}
      MYSQL_USER: ${LH_MYSQL_USER}
      MYSQL_PASSWORD: ${LH_MYSQL_PASSWORD}
    extra_hosts:
      - "host.docker.internal:host-gateway"
  database:
    env_file:
      - .env
    build:
      context: ./bin/${LH_DATABASE}
    container_name: ${LH_SYSTEM_NAME}-${LH_DATABASE}
    restart: always
    networks:
      - lamp-network
    ports:
      - "127.0.0.1:${LH_HOST_MACHINE_MYSQL_PORT}:${LH_HOST_MACHINE_MYSQL_PORT}"
    volumes:
      - ${LH_MYSQL_INITDB_DIR}:/docker-entrypoint-initdb.d
      - ${LH_MYSQL_DATA_DIR}:/var/lib/mysql
      - ${LH_MYSQL_LOG_DIR}:/var/log/mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${LH_MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${LH_MYSQL_DATABASE}
      MYSQL_USER: ${LH_MYSQL_USER}
      MYSQL_PASSWORD: ${LH_MYSQL_PASSWORD}
  phpmyadmin:
    env_file:
      - .env
    container_name: ${LH_SYSTEM_NAME}-phpmyadmin
    image: phpmyadmin/phpmyadmin
    restart: always
    depends_on:
      - database
    environment:
      VIRTUAL_HOST: ${LH_PHPMYADMIN_DOMAIN}
      PMA_HOST: database
      PMA_PORT: 3306
      PMA_USER: root
      PMA_PASSWORD: ${LH_MYSQL_ROOT_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${LH_MYSQL_ROOT_PASSWORD}
      MYSQL_USER: ${LH_MYSQL_USER}
      MYSQL_PASSWORD: ${LH_MYSQL_PASSWORD}
      UPLOAD_LIMIT: ${LH_UPLOAD_LIMIT}
      MEMORY_LIMIT: ${LH_MEMORY_LIMIT}
    volumes:
      - /sessions
      - ${LH_PHP_INI}:/usr/local/etc/php/conf.d/php-phpmyadmin.ini
    networks:
      - lamp-network
networks:
  lamp-network:
    driver: bridge
  1. 我使用另一种方法更改了 Dockerfile 中的脚本:
FROM php:8.1-apache-bullseye

ARG DEBIAN_FRONTEND=noninteractive

RUN a2enmod rewrite headers

RUN service apache2 restart

RUN apt-get update &&  \
    apt-get upgrade -y --no-install-recommends --fix-missing

RUN apt-get install -y --no-install-recommends --fix-missing build-essential dialog nano apt-utils cron wget git curl zip openssl

RUN apt-get -y autoremove && \
    apt-get clean

RUN rm -rf /usr/src/* && \
    rm -rf /var/lib/apt/lists/*

RUN mkdir -p /var/log/cron && \
    chmod 755 /var/log/cron && \
    touch /var/log/cron/cron.log

RUN echo "* * * * * root /var/www/html/Asset/resource/cron/cron.sh >> /var/log/cron/cron.log 2>&1" > /etc/cron.d/cron-task && \
    chmod 0644 /etc/cron.d/cron-task

CMD cron && /usr/local/bin/apache2-foreground && chmod +x /var/www/html/Asset/resource/cron/cron.sh && tail -f /var/log/cron/cron.log

最重要的是实现 CMD 来解决几乎所有检测到的问题,并从 Dockerfile 创建文件而不是挂载它们。

我不确定这是否是正确的方法或最好的方法,但这确实是唯一可行的方法。

补充笔记:

  • 重要的是要在的开头合并实现图像的入口点或CMD,因为使用CMD替换默认值CMD会导致问题。
  • 同样重要的是,如果tail...被实现,它必须在最后完成,因为这通常会阻止脚本和执行。

相关内容