Dépannage · Laravel
Le scheduler Laravel ne tourne pas ? Corrigez l’échec silencieux
Pourquoi le scheduler de Laravel s’arrête en silence — l’entrée cron manquante, le mauvais utilisateur, l’environnement et les tâches qui se chevauchent — et comment y remédier.
Le scheduler de Laravel est piloté par une seule entrée cron système. Si elle est incorrecte — ou l’environnement sous-jacent — toutes les tâches planifiées s’arrêtent en silence. Voici la checklist.
1. L’unique entrée cron doit exister
Laravel a besoin d’exactement une ligne de crontab appelant schedule:run chaque
minute. Vérifiez qu’elle existe pour le bon utilisateur (généralement votre
utilisateur de déploiement, pas root) :
crontab -l
Elle doit être :
* * * * * cd /var/www/app && php artisan schedule:run >> /dev/null 2>&1
Si elle manque, ajoutez-la avec crontab -e. Une erreur de déploiement courante est
de l’ajouter en tant que root alors que l’app tourne en tant que www-data (ou
inversement).
2. Utilisez le bon binaire PHP et un chemin absolu
Sous cron, php peut ne pas se résoudre, ou être la mauvaise version. Utilisez le
chemin complet et celui du projet :
* * * * * cd /var/www/app && /usr/bin/php8.3 artisan schedule:run >> /dev/null 2>&1
3. L’environnement diffère de votre shell
Cron ne charge pas votre profil shell, donc tout ce que vous y définissez manque.
Laravel lit .env, ce qui est bien — mais si vos tâches appellent d’autres
binaires, donnez-leur un PATH explicite. Assurez-vous aussi que APP_ENV et la
configuration des files/cache correspondent à la production.
4. Vous avez masqué la sortie et ne pouvez plus déboguer
>> /dev/null 2>&1 cache tout, y compris les erreurs. Journalisez-la
temporairement :
* * * * * cd /var/www/app && php artisan schedule:run >> storage/logs/schedule.log 2>&1
Puis exécutez php artisan schedule:run à la main et lisez la sortie — la plupart
des échecs (permissions, env manquant, connexion BD) apparaissent immédiatement.
5. Les tâches se chevauchent ou se bloquent
Une tâche longue qui tourne chaque minute peut s’accumuler. Utilisez les garde-fous de Laravel pour qu’une exécution lente ne bloque pas la suivante :
$schedule->command('reports:build')
->hourly()
->withoutOverlapping()
->onOneServer();
Le problème de fond : le scheduler peut s’arrêter et rester silencieux
Si schedule:run cesse de se déclencher — le serveur a redémarré, la crontab a été
effacée au déploiement, PHP a été mis à jour — Laravel n’a aucun moyen de vous le
dire. Vos rapports et e-mails en file s’arrêtent tout simplement.
Envoyez un ping heartbeat depuis une tâche planifiée pour savoir que le scheduler lui-même est vivant :
$schedule->call(function () {
Http::timeout(10)->get('https://ping.steadycron.com/<votre-jeton-ping>');
})->everyFifteenMinutes();
Si ce ping manque, SteadyCron vous alerte — le scheduler est en panne, avant que vos utilisateurs ne s’en aperçoivent.