К основному содержимому

PHP в cron: чем CLI отличается от FPM на практике

PHP · 29.09.2026

Чем PHP CLI отличается от PHP-FPM для cron-задач

PHP-FPM обслуживает HTTP-запросы через Nginx и работает в режиме пула воркеров с общим php.ini и лимитами, заданными для веб-нагрузки. PHP CLI — это отдельный бинарник /usr/bin/php8.3, который запускается из командной строки или из crontab и читает свой собственный конфиг, обычно из /etc/php/8.3/cli/php.ini. Значения memory_limit, max_execution_time и error_reporting в CLI и FPM могут отличаться, и это частая причина, почему скрипт в браузере работает, а тот же скрипт по расписанию падает или наоборот.

Второе отличие — окружение. У процесса cron нет переменных PATH, HOME и локали, которые есть у интерактивной оболочки, и нет рабочего каталога по умолчанию: он всегда стартует из домашнего каталога пользователя, от которого запущен cron.

Как правильно прописать задачу в crontab

Правило crontab должно указывать полный путь к бинарнику PHP, полный путь к скрипту и рабочий каталог, если скрипт использует относительные пути к файлам.

*/5 * * * * cd /var/www/app && /usr/bin/php8.3 artisan schedule:run >> /var/log/app/cron.log 2>&1

Символ && гарантирует, что php запустится только после успешного перехода в каталог, а 2>&1 перенаправляет ошибки в тот же лог-файл, что и обычный вывод. Без этого фатальные ошибки PHP молча исчезают: cron отправляет их на локальную почту, которую никто не читает.

Своя версия php.ini для CLI

Проверить, какой конфиг реально использует CLI, можно одной командой — она покажет путь к файлу, а не предположение.

php --ini
php -i | grep memory_limit

Если на сервере установлено несколько версий PHP, как описано в статье о нескольких версиях PHP на одном сервере, в crontab обязательно указывайте версию явно: /usr/bin/php8.3, а не просто php — иначе задача может внезапно выполниться под другой версией после обновления alternatives.

Память, таймауты и рабочий каталог: частые грабли

ПараметрВеб (FPM)Cron (CLI)
memory_limit128Mчасто без ограничения (-1)
max_execution_time30 секунд0, ограничения нет
рабочий каталогкорень сайтадомашний каталог пользователя
error_logлог PHP-FPMstderr, если не задан явно

Значения из таблицы задаются в разных секциях php.ini: [PHP] влияет на оба режима, а блок cli/conf.d — только на CLI. Управление памятью и загрузкой подробно разобрано в статье про memory_limit и upload_max_filesize.

Логирование вывода cron-задач

  • Всегда перенаправляйте stdout и stderr в отдельный файл лога, а не полагайтесь на почту cron.
  • Указывайте display_errors = Off и log_errors = On в cli/php.ini — вывод ошибок в консоль ломает формат, если скрипт печатает JSON или CSV.
  • Ротацию log-файла cron настраивайте через logrotate, иначе файл вырастет до гигабайтов за месяц.
  • Разбор упавших задач начинайте с error_log, а не с догадок — принципы разобраны в статье про логи PHP и разбор фаталов.
  • Добавляйте в начало каждой задачи date и hostname в лог — на кластере из нескольких серверов иначе не понять, кто именно писал в лог.

Итог: чек-лист для PHP-задач в cron

  • В crontab указан полный путь к бинарнику нужной версии PHP и рабочий каталог через cd.
  • Вывод команды перенаправлен в файл лога с ротацией через logrotate.
  • Проверены memory_limit и max_execution_time именно в cli/php.ini, а не в конфиге FPM.
  • display_errors выключен, log_errors включён, ошибки идут в файл, а не в почту root.
  • Задача проверена вручную от имени того же пользователя, от которого её запускает cron.
← Назад в базу знаний Задать вопрос поддержке