自由學習的風

幽夢影 張潮 少年讀書,如隙中窺月;中年讀書,如庭中望月;老年讀書,如臺上玩月。皆以閱歷之淺深,為所得之淺深耳。

Laravel 排程在 Docker 中執行

2026年7月28日 星期二

Laravel 專案有排程要執行,但是 php-fpm container 裡沒有 crontab 指令,這是很常見的情況。

這時候不要急著把 cron 裝進 php-fpm。php-fpm 本來是處理網站 request 的,排程可以用別的方式做。

需求:

要定時執行:

php artisan forum:sync

例如每天 4 點和 15 點各執行一次。

方法一:由 Linux 主機 crontab 執行

可以直接在 host 的 crontab 裡呼叫 container 裡的 artisan:

docker exec -w /var/www/default php-fpm php artisan forum:sync

先手動測一次:

docker exec -w /var/www/default php-fpm php artisan forum:sync

如果可以正常執行,再加入 crontab:

crontab -e

每天 04:00 和 15:00 執行:

0 4,15 * * * /usr/bin/flock -n /tmp/forum-sync.lock /usr/bin/docker exec -w /var/www/default php-fpm php artisan forum:sync >> /var/log/forum-sync.log 2>&1

指令說明:

  1. 0 4,15 * * *

每天 4 點和 15 點執行。

  1. /usr/bin/flock -n /tmp/forum-sync.lock

避免上一輪還沒跑完,下一輪又啟動。

  1. /usr/bin/docker exec

從 host 執行 container 裡的指令。

  1. -w /var/www/default

指定 Laravel 專案所在目錄。

  1. >> /var/log/forum-sync.log 2>&1

把執行結果和錯誤訊息寫入 log。

方法二:建立 scheduler container

如果想比較 Docker 化,也可以另外建立一個 scheduler service:

laravel-scheduler:
  image: "${PHP_VERSION}"
  container_name: laravel-scheduler
  working_dir: /var/www/default
  volumes:
    - ./wwwroot:/var/www
    - ./session:/var/lib/php/session
  environment:
    TZ: ${TZ}
  command: sh -c "while true; do php artisan schedule:run --verbose --no-interaction; sleep 60; done"
  restart: unless-stopped
  depends_on:
    - mysql

啟動:

docker compose up -d laravel-scheduler

這種方式適合有使用 Laravel scheduler,也就是在 app/Console/Kernel.php 裡集中管理排程的專案。

常見錯誤:

如果出現:

Could not open input file: artisan

代表 -w /var/www/default 不是 Laravel 專案所在目錄,要改成實際路徑。

如果實際使用 PHP 8.3 container,就要把 container 名稱改成:

php83-fpm

結論:

php-fpm 裡沒有 crontab 不算問題。

簡單需求可以用 host crontab 呼叫:

docker exec ...

比較完整的 Laravel 排程,則可以用獨立 scheduler container。

不要把所有功能都塞進 php-fpm,之後比較好維護。

0 意見:

張貼留言