13

I have a container with for my laravel app with php:7.0.4-fpm as base image.

This is my 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
  1. Cron is not running, I have to ssh in the container to launch it.
  2. When I start it manually it works for som simple things like echoing a text every minute. But not for the php artisan schedule:run command. In the log I see :

    Running scheduled command: '/usr/local/bin/php' 'artisan' errors:insert > '/dev/null' 2>&1

errors:insert is the name of my task, but nothing is update in the website.

  1. That's strange because when I run php artisan schedule:run command manually it works on the website.

So my question is : How to make cron work on a docker container to execute the php artisan schedule:run command ? Preferably written in a dockerfile and not manually via ssh.

I also have a strange message from the container :

ALERT: oops, unknown child (5094) exited with code 1.
Please open a   bug report (https://bugs.php.net).
2
  • 1
    You have to start it manually, because cron must be executed run-time, therefore it should be in the ENTRYPOINT instead of a RUN. However, for the second part I experience the same, but with exit code 0, did you manage to solve it? Commented Jun 13, 2017 at 12:50
  • I solved it with another way. I used one container to do everything with supervisor. Commented Jul 10, 2017 at 7:46

2 Answers 2

10

An alternative solution could be by running php artisan schedule:run with supervisor. In my case I have a schedule-run.conf in [project root]/.docker/php/workers:

[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
  • replace your apt-get install -y cron by apt-get install -y supervisor
  • add ADD .docker/php/workers /etc/supervisor/conf.d and CMD ["/usr/bin/supervisord"] to your Dockerfile.
Sign up to request clarification or add additional context in comments.

2 Comments

Nice one! You usually need supervisor anyway for the queue workers. But i would not run this as root.
You're right about the use of root. I would use another user in a production scenario, like www or www-data.
5

Though this is a late reply but I thought my solution might help others as I have faced this issue before.

I created separate docker container as Laravel Docker Cron for performing laravel schedules

Here my Dockerfile code

FROM ubuntu:latest
MAINTAINER [email protected]

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 file will contain

* * * * * 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.

Here is repo for this code click here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.