在与 Docker 捣鼓了几天之后,我还没有找到解决问题的方法。
简而言之,我尝试添加cron
并php: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 实用程序集成到容器中并使其保持工作之后,这是必要的:
- 从我的 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
- 我使用另一种方法更改了 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
...被实现,它必须在最后完成,因为这通常会阻止脚本和执行。