How can I automatically start cron in a Docker container that is running PHP?

Viewed 2555

I'm trying to run some PHP scripts automatically and want to have cron running once the container starts. Below is my current Dockerfile but upon running the docker-compose up -d command, the PHP container crashes immediately and I get the errors Cannot start service composer: Cannot link to a non running container and Cannot start service apache: Cannot link to a non running container which makes sense, because the PHP container already crashed. I've also tried CMD ["cron", "-f"] in place of CMD cron start && tail -f /var/log/cron.log and all the containers run, and the test job is executed, but I get a 503 service unavailable error when trying to access the app. From what I've read this is because cron is running in the foreground and blocking PHP.

Dockerfile

FROM php:7.4.2-fpm-buster

RUN apt-get update && apt-get install -y \
        freetds-bin \
        freetds-dev \
        freetds-common \
        libct4 \
        libsybdb5 \
        tdsodbc \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libpng-dev \
        libldap2-dev \
        libpq-dev \
        zlib1g-dev \
        libc-client-dev \
        libzip-dev \
        zip \
        cron

RUN ln -s /usr/lib/x86_64-linux-gnu/libsybdb.a /usr/lib/
RUN ln -s /usr/lib/x86_64-linux-gnu/libpq-fe.h /usr/lib/

RUN docker-php-ext-install pdo pdo_mysql pdo_dblib pdo_pgsql gd zip

RUN apt-get install unixodbc unixodbc-dev -y \
 && docker-php-ext-configure pdo_odbc --with-pdo-odbc=unixODBC,/usr \
 && docker-php-ext-install pdo_odbc

COPY ./freetds.conf /etc/freetds/freetds.conf
COPY ./odbc.ini /etc/odbc.ini
COPY ./odbcinst.ini /etc/odbcinst.ini
COPY ./php.ini /usr/local/etc/php

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

RUN mkdir /var/www/html/files && chown -R www-data:www-data /var/www/html/files && chmod -R 755 /var/www/html/files
RUN mkdir /var/www/html/exports && chown -R www-data:www-data /var/www/html/exports && chmod -R 755 /var/www/html/exports
RUN mkdir /var/www/html/scripts && chown -R www-data:www-data /var/www/html/scripts && chmod -R 755 /var/www/html/scripts

# copying cronjobs, a file I created with a test cronjob to /etc
COPY ./cronjobs /etc
# using the cronjobs file I created as the crontab
RUN crontab /etc/cronjobs

CMD cron start && tail -f /var/log/cron.log

EXPOSE 9000

docker-compose.yml (some info redacted ... the xxx parts)

version: "3.7"
services:
  php:
    build: './php/'
    links:
      - 'mysql'
    network_mode: "bridge"
    ports:
      - "xxxx:9000"
    volumes:
      - ./www/:/var/www/html/
      - files:/var/www/html/files
  apache:
    build: './apache/'
    depends_on:
      - php
    links:
      - 'php'
    network_mode: "bridge"
    ports:
      - "xxxx:80"
    volumes:
      - ./www/:/var/www/html/
      - files:/var/www/html/files
  mysql:
    image: mysql:latest
    command: --init-file /docker-entrypoint-initdb.d/init.sql
    environment:
      MYSQL_ROOT_PASSWORD: 'xxx'
      MYSQL_USER: 'xxx'
      MYSQL_PASS: 'xxx'
    ports:
      - "xxxx:3306"
    network_mode: "bridge"
    volumes:
      - data:/var/lib/mysql
      - ./mysql/init:/docker-entrypoint-initdb.d
  phpmyadmin:
    depends_on: 
      - mysql
    environment:
      PMA_HOST: mysql
      PMA_PORT: 3306
    image: phpmyadmin/phpmyadmin
    links:
      - mysql
    network_mode: "bridge"
    ports:
      - "xxxx:80"
  composer:
    container_name: composer
    depends_on:
      - php
    links:
      - 'php'
    image: composer
    network_mode: "bridge"
    volumes:
      - ./www:/var/www/html/
    command: composer install --ignore-platform-reqs && composer require phpoffice/phpspreadsheet
networks:
  default:
    external:
      name: bridge
volumes:
  data:
  files:

cronjobs file

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

42 22 * * * /usr/local/bin/php /var/www/html/scripts/test.php
0 Answers
Related