Introduction
Hier soir, j’ai rencontré un problème assez critique sur mon VPS : tous mes sites affichaient une erreur HTTP 500. Le comportement était très étrange :
- La page affichait une erreur 500 ("Connection timed out" côté Nginx).
- Après un rafraîchissement, le site fonctionnait à nouveau.
- Quelques minutes plus tard, en cliquant sur un autre lien, l’erreur revenait.
Au début, je pensais que le problème venait d’un projet Laravel spécifique, mais après vérification, tous les sites hébergés sur mon VPS étaient concernés. Voici comment j’ai analysé ce comportement et résolu le vrai problème de fond.
1. Les fausses pistes (Les bons réflexes à avoir)
Face à une erreur 500 sur Laravel, les causes les plus fréquentes sont généralement des mauvaises permissions ou un cache corrompu. Voici les étapes classiques que j'ai d'abord suivies :
Vérification de la version PHP et du Cache Laravel :
J'ai vérifié ma version CLI (php --ini), qui était bien en PHP 8.3. J'ai ensuite nettoyé le cache de mon application pour repartir sur une base saine :
bash php artisan optimize:clear
Vérification des permissions :
J'ai également réattribué les droits à l'utilisateur web pour être sûr que FPM pouvait écrire dans les dossiers :
bash chown -R www-data:www-data /var/www chmod -R 775 storage bootstrap/cache
Malgré ces étapes et le redémarrage des services, l'erreur 500 continuait de revenir au bout d'une vingtaine de minutes. Plus étrange encore : le fichier storage/logs/laravel.log était totalement vide. Si Laravel ne loguait rien, cela signifiait que le crash se produisait avant même que l'application ne s'exécute.
2. Le vrai coupable : Les logs système FPM
Puisque l'erreur 500 masquait la véritable erreur et touchait tous les sites, il fallait regarder plus bas, au niveau du gestionnaire de processus PHP-FPM.
J'ai lancé cette commande pour observer les logs système en direct :
bash tail -f /var/log/php8.3-fpm.log /var/log/nginx/error.log
Bingo ! J'ai vu apparaître ceci :
text WARNING: [pool www] child 8869 exited on signal 11 (SIGSEGV - core dumped) after 1492.295670 seconds from start
Une erreur SIGSEGV (Signal 11 - Segmentation Fault). Cela signifie que le processus (le "worker") PHP a tenté d'accéder à une mémoire corrompue et a planté brutalement. Nginx attendait donc une réponse d'un processus mort, causant l'erreur 500, jusqu'à ce que FPM recrée un nouveau worker (d'où le fait que ça remarchait après un "refresh").
Sur PHP 8.3, ce bug de "segfault" est souvent lié à des fuites de mémoire, au compilateur JIT d'OPcache, ou à une corruption de la base de données temporelle du système d'exploitation.
3. La solution définitive
Pour régler ce problème, il faut agir sur plusieurs tableaux : forcer le recyclage des processus, désactiver la fonctionnalité instable d'OPcache, et réparer la librairie système responsable des fuseaux horaires.
Étape 1 : Forcer le recyclage des workers PHP-FPM
Par défaut, les workers peuvent tourner indéfiniment. J'ai modifié la configuration du pool FPM pour les tuer et les recréer proprement toutes les 500 requêtes.
bash sudo nano /etc/php/8.3/fpm/pool.d/www.conf
J'ai décommenté et modifié cette ligne :
text pm.max_requests = 500
Étape 2 : Désactiver le JIT d'OPcache
Pour éviter les crashs de compilation mémoire, j'ai désactivé le JIT dans le fichier de configuration principal.
bash sudo nano /etc/php/8.3/fpm/php.ini
J'ai ajouté :
text opcache.jit=disable
Étape 3 : Réparer la base de données des fuseaux horaires (tzdata)
Un cas extrêmement fréquent provoquant ce type d'erreur 500 inexpliquée est l'impossibilité pour PHP de lire les informations du fuseau horaire du système (erreur fatale Timezone database is corrupt). Pour écarter ce problème lié à l'OS, il est fortement recommandé de réinstaller proprement le paquet tzdata (sur Debian/Ubuntu) :
bash sudo apt-get install --reinstall tzdata
Vous verrez alors un prompt confirmant votre fuseau horaire par défaut (ex: Africa/Porto-Novo). Assurez-vous ensuite d'avoir la même valeur définie dans la directive date.timezone de votre php.ini.
Étape 4 : Redémarrage
Il ne restait plus qu'à appliquer toutes ces configurations :
bash systemctl restart php8.3-fpm systemctl restart nginx
Conclusion
Les erreurs HTTP 500 sur un VPS peuvent être trompeuses. Quand toutes vos applications plantent simultanément, que vos logs Laravel sont vides et que le site revient à la vie après un simple F5, ne cherchez pas dans votre code PHP.
Le réflexe en or est de toujours vérifier /var/log/phpX.X-fpm.log.
Commentaires
Aucun commentaire pour l'instant. Soyez le premier à réagir !
Laisser un commentaire
Votre commentaire sera modéré avant publication.