Article

Legacy PHP CLI and Cron Modernization

Run cron and CLI PHP with the correct binary, ini, working directory, locking, and logging so scheduled jobs stop failing silently after upgrades.

Cron jobs often call php from PATH and inherit a different php.ini than FPM. After a host upgrade, the web app runs PHP 8.2 while nightly billing still hits PHP 7.2—or the reverse. Modernization makes the binary, ini, working directory, and locks explicit.

LEGACY — ambiguous cron
0 2 * * * cd /var/www/app && php scripts/bill.php
MODERN — pinned binary + logging + lock
0 2 * * * /usr/bin/flock -n /tmp/app-bill.lock /opt/php82/bin/php -c /etc/php/8.2/cli/php.ini /var/www/app/scripts/bill.php >> /var/log/app/bill.log 2>&1

Checklist

  • Same major.minor PHP as the app unless intentionally different
  • Working directory set so relative includes resolve
  • Environment variables available (cron has a minimal env)
  • Overlap locking so a slow run does not start a second copy
  • Timeouts and log rotation
  • Timezone awareness for schedules
  • systemd timers where they fit operations better than crontab

Validate schedules with Cron Expression Helper. Compare CLI vs FPM with Environment Compare. Manual: Command line usage.

Related reading