用于laravel的docker容器上的cron无法正常工作

Posted

技术标签:

【中文标题】用于laravel的docker容器上的cron无法正常工作【英文标题】:cron on a docker container for laravel not working 【发布时间】:2017-10-26 16:20:00 【问题描述】:

我的 laravel 应用程序有一个容器,其中 php:7.0.4-fpm 作为基础镜像。

这是我的 dockerfile:

FROM php:7.0.4-fpm

RUN apt-get update && apt-get install -y cron nano libmcrypt-dev \
    mysql-client libmagickwand-dev --no-install-recommends \
    && pecl install imagick \
    && docker-php-ext-enable imagick \
    && docker-php-ext-install mcrypt pdo_mysql

COPY . /var/www

ADD crontab /etc/cron.d/laravel-cron

RUN chmod 0644 /etc/cron.d/laravel-cron

RUN touch /var/log/cron.log

RUN /usr/bin/crontab /etc/cron.d/laravel-cron

RUN cron
    Cron 没有运行,我必须在容器中 ssh 才能启动它。

    当我手动启动它时,它适用于一些简单的事情,比如每分钟回显一个文本。但不适用于 php artisan schedule:run 命令。在我看到的日志中:

    运行预定命令:'/usr/local/bin/php''artisan' 错误:插入 > '/dev/null' 2>&1

errors:insert 是我的任务名称,但网站上没有任何更新。

    这很奇怪,因为当我手动运行 php artisan schedule:run 命令时,它可以在网站上运行。

所以我的问题是:如何让 cron 在 docker 容器上工作以执行 php artisan schedule:run 命令?最好写在 dockerfile 中,而不是通过 ssh 手动编写。

我还有一个来自容器的奇怪消息:

ALERT: oops, unknown child (5094) exited with code 1.
Please open a   bug report (https://bugs.php.net).

【问题讨论】:

你必须手动启动它,因为cron必须在运行时执行,因此它应该在ENTRYPOINT而不是RUN。但是,对于第二部分,我遇到了相同的情况,但是退出代码为 0,您设法解决了吗? 我用另一种方式解决了它。我使用一个容器与主管一起完成所有工作。 【参考方案1】:

另一种解决方案是使用主管运行php artisan schedule:run。就我而言,我在 [project root]/.docker/php/workers 中有一个 schedule-run.conf:

[program:schedule-run]
process_name=%(program_name)s_%(process_num)02d
command=/bin/bash -c "while [ true ]; do (php /var/www/html/artisan 
schedule:run --verbose --no-interaction &); sleep 60; done"
autostart=true
autorestart=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/html/storage/logs/schedule.log
stopwaitsecs=60
将您的apt-get install -y cron 替换为apt-get install -y supervisorADD .docker/php/workers /etc/supervisor/conf.dCMD ["/usr/bin/supervisord"] 添加到您的Dockerfile。

【讨论】:

不错的一个!无论如何,队列工作人员通常都需要主管。但我不会以 root 身份运行它。 你是对的使用root。我会在生产场景中使用另一个用户,例如 wwwwww-data【参考方案2】:

虽然这是一个迟到的回复,但我认为我的解决方案可能会帮助其他人,因为我以前遇到过这个问题。

我创建了单独的 docker 容器作为 Laravel Docker Cron 来执行 laravel 调度

这是我的 Dockerfile 代码

FROM ubuntu:latest
MAINTAINER docker@ekito.fr

ENV DEBIAN_FRONTEND=noninteractive

# install base packages
RUN apt-get update && apt-get -y install cron\

    apt-utils \
    curl \

    # Install php 7.2
    php7.2 \
    php7.2-cli \
    php7.2-json \
    php7.2-curl \
    php7.2-fpm \
    php7.2-dev \
    php7.2-gd \
    php7.2-ldap \
    php7.2-mbstring \
    php7.2-bcmath \
    php7.2-mysql \
    php7.2-soap \
    php7.2-sqlite3 \
    php7.2-xml \
    php7.2-zip \
    php7.2-intl \
    libldap2-dev \
    libaio1 \
    libaio-dev

# Install tools
RUN apt-get -y install openssl \
    nano \
    ghostscript \
    iputils-ping \
    locales \
    rlwrap \
    php-pear \
    make \
    unzip \
    zip \
    tar \
    ca-certificates \
    && apt-get clean &&\

# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Set locales
RUN locale-gen en_US.UTF-8 en_GB.UTF-8 de_DE.UTF-8 es_ES.UTF-8 fr_FR.UTF-8 it_IT.UTF-8 km_KH sv_SE.UTF-8 fi_FI.UTF-8

# Copy crontab file to the cron.d directory
COPY crontab /etc/cron.d/crontab

# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/crontab

# Apply cron job
RUN crontab /etc/cron.d/crontab

# Create the log file to be able to run tail
RUN touch /var/log/cron.log

# Run the command on container startup
CMD cron && tail -f /var/log/cron.log

crontab 文件将包含

* * * * * cd /var/www && php artisan schedule:run >> /var/log/cron.log 2>&1
# An empty line is required at the end of this file for a valid cron file.

这里是此代码的仓库click here

【讨论】:

以上是关于用于laravel的docker容器上的cron无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

在不同主机上的 Docker 中运行 cron 的问题

关于docker容器cron定时任务的执行

如何在 docker 容器中运行 cron 作业

当我启动我的 docker 容器时,Cron 没有运行

docker ubuntu cron -f 不工作

在我将 cron 文件重新保存在 docker 容器中之前,Cron 作业不起作用