Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як запускати планувальник задач Laravel у Docker: cron чи schedule:work?

На звичайному сервері планувальник запускається рядком у crontab:

* * * * * cd /var/www/html && php artisan schedule:run >> /dev/null 2>&1

schedule:run щохвилини перевіряє, які задачі настав час виконати, і завершується.

У Docker є два підходи.

1. schedule:work - окремий контейнер (рекомендовано):

services:
  scheduler:
    image: myapp:1.4.0
    command: php artisan schedule:work
    restart: unless-stopped

schedule:work - процес на передньому плані, який сам щохвилини викликає schedule:run. Не потрібен cron-демон, вивід іде в stdout (видно в docker logs), сигнали зупинки обробляються коректно.

2. cron усередині контейнера:

RUN apt-get install -y cron && echo "* * * * * www-data php /var/www/html/artisan schedule:run" > /etc/cron.d/laravel
CMD ["cron", "-f"]

Недоліки: cron не передає дочірнім процесам змінні оточення контейнера (треба їх окремо зберігати й підставляти), вивід задач не потрапляє в логи Docker, потрібен root для cron-демона.

3. Зовнішній планувальник - cron на хості, Kubernetes CronJob чи планувальник платформи запускає разовий контейнер з php artisan schedule:run. Корисно, якщо платформа не любить постійно запущених процесів без роботи.

Обов'язкові правила:

  • рівно один планувальник. Якщо масштабувати контейнер scheduler до двох реплік чи запускати schedule:run у кожному вебконтейнері, кожна задача виконається кілька разів - листи підуть двічі, звіти згенеруються двічі;
  • для задач, які взагалі не можна дублювати, - ->onOneServer() (атомарне блокування в спільному кеші) і ->withoutOverlapping(), щоб довга задача не стартувала вдруге, поки працює перша;
  • довгі задачі - в черзу (->runInBackground() чи задача, що ставить job), щоб не блокувати інші задачі цієї хвилини;
  • таймзона: ->timezone('Europe/Kyiv') чи schedule_timezone у конфігурації - інакше «щодня о 9:00» означатиме 9:00 UTC.

Докладніше в документації: Laravel: запуск планувальника

Схожі питання