Docker 排程

Docker 排程

在 docker 我們會建立自己專案的環境,讓他可以運行我們的專案、看是 php、python、golang … 之類的運行環境,而專案會需要定期排程去執行指定的程式,以下以 Laravel 為例

建立自訂 crontab 檔案

在專案下會建立一個 crontab 指令的檔案 my_laravel_docker_crontab

每分鐘會切換到 Laravel 專案目錄下 /my/laravel/app/ 並執行 php artisan schedule:run 的指令執行排程

# my_laravel_docker_crontab
# m h  dom mon dow   command
# 預設有 bin/bash 環境
* * * * * cd /my/laravel/app/ && php artisan schedule:run >> /dev/null 2>&1

# 如果你的 docker 環境不是預設使用 bin/bash 環境
* * * * * /bin/bash -l -c 'cd /my/laravel/app/ && php artisan schedule:run >> /dev/null 2>&1'

環境安裝 cron

映像檔通常是最小單位的檔案,所以不會有 cron 的排程程式,所以在建立 Docker 環境時必須要自己指定去安裝 cron 軟體,這樣就可以在我們自己自定義的環境去跑 cron 定期排程去執行程式

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

加入自訂的 crontab 檔案

在 docker 專案下將 crontab 指令的檔案 my_laravel_docker_crontab 複製到 docker 的目錄下,並指定 crontab 去執行此 crontab 檔案

# 加入 docker 專案的自訂 crontab
ADD my_laravel_docker_crontab /etc/cron.d/my_laravel_docker_crontab

# 變更 crontab 檔案權限
RUN chmod 0644 /etc/cron.d/my_laravel_docker_crontab


# 指定 crontab 檔案
RUN crontab /etc/cron.d/my_laravel_docker_crontab

執行 crontab

在最後使用指令執行 crontab,這樣就可以開始每分鐘定期執行程式了

# 執行 crontab
CMD ["cron", "-f"]

完整程式碼

以下是完整的 Dockerfile 檔案 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

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

# 加入 docker 專案的自訂 crontab
ADD my_laravel_docker_crontab /etc/cron.d/my_laravel_docker_crontab

# 變更 crontab 檔案權限
RUN chmod 0644 /etc/cron.d/my_laravel_docker_crontab

# 指定 crontab 檔案
RUN crontab /etc/cron.d/my_laravel_docker_crontab

# 執行 crontab
CMD ["cron", "-f"]

docker-compose.yml 檔案會去執行剛剛的 laravel.cron.Dockerfile 檔案,這樣就可以定期去執行 Laravel 的排程程式了

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

參考資料