Docker Scheduling

Docker Scheduling

We will build the specific environment for running our projects in docker. Such as using PHP, Python, Golang. But sometimes we need to run the specific tasks at a specific time regularly and automatically. We will use crontab to achieve our goal. But what if we want to get the same result on docker? Here is the example by using Laravel.

Create custom crontab file for laravel

Create the custom crontab file in the project that names my_laravel_docker_crontab

crontab will change the working directory to laravel project /my/laravel/app/ then execute php artisan schedule:run command for our Laravel schedule

# my_laravel_docker_crontab
# m h  dom mon dow   command
# use the bin/bash as the default environment
* * * * * cd /my/laravel/app/ && php artisan schedule:run >> /dev/null 2>&1

# If your docker doesn't use the bin/bash as the default environment
* * * * * /bin/bash -l -c 'cd /my/laravel/app/ && php artisan schedule:run >> /dev/null 2>&1'

Install cron application on docker container

Docker images is minimize unit for specific usage without cron. So it should be install by yourself on our specific environment in docker. And scheduling to run tasks that we want to do.

RUN apt-get update && apt-get install -y cron

Add custom crontab file

We will copy the custom crontab file my_laravel_docker_crontab to docker images. and specify crontab to run this tasks scheduling.

# Add docker custom crontab
ADD my_laravel_docker_crontab /etc/cron.d/my_laravel_docker_crontab

# Update the crontab file permission
RUN chmod 0644 /etc/cron.d/my_laravel_docker_crontab

# Specify crontab file for running
RUN crontab /etc/cron.d/my_laravel_docker_crontab

Executing crontab

Finally, we will execute command cron -f to execute our cron tasks every minutes.

# execute crontab
CMD ["cron", "-f"]

Here is the full version of the crontab laravel.cron.Dockerfile

# laravel.cron.Dockerfile
FROM php:8-fpm

RUN apt-get update && apt-get install -y cron libpq-dev libzip-dev zip unzip curl \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libmagickwand-dev \
    --no-install-recommends \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) gd \
    && pecl install imagick \
    && docker-php-ext-enable imagick \
    && docker-php-ext-install pgsql pdo_pgsql zip\
    && docker-php-ext-enable opcache

# Install redis
RUN pecl install -o -f redis \
  &&  rm -rf /tmp/pear \
  &&  docker-php-ext-enable redis

# Add docker custom crontab
ADD my_laravel_docker_crontab /etc/cron.d/my_laravel_docker_crontab

# Update the crontab file permission
RUN chmod 0644 /etc/cron.d/my_laravel_docker_crontab

# Specify crontab file for running
RUN crontab /etc/cron.d/my_laravel_docker_crontab

# execute crontab
CMD ["cron", "-f"]

Run docker-compose

We will set the setting in docker-compose.yml to run our Dockerfile. And execute docker-compose up -d to running this cronjob container in background

# docker-compose.yml
version: '3'

services:
  cronjob:
    container_name: laravel_cronjob
    build: laravel.cron.Dockerfile
    image: laravel_cronjob:v1.0
    volumes:
      - /home/KJ/laravel_app:/my/laravel/app/
    restart: always
docker-compose up -d cronjob

Reference