Nginx et Laravel - La config parfaite pour éviter les erreurs!

Léon Weiss .

2 mars 2026

Configuration Nginx pour un site web, incluant les directives pour Laravel et le traitement PHP.

Déployer une application Laravel derrière Nginx ne consiste pas seulement à faire répondre le serveur sur le port 80. Il faut surtout que chaque requête arrive au bon endroit, que les fichiers sensibles restent hors de portée, et que l’application soit prête pour une vraie mise en production. Je pars toujours d’une base simple: Nginx en façade, PHP-FPM pour exécuter PHP, puis quelques réglages Laravel qui évitent les erreurs de routage, les lenteurs inutiles et les incidents de déploiement.

Les points qui changent vraiment le résultat en production

  • Le serveur web doit pointer vers `public/`, jamais vers la racine du projet.
  • `try_files` et `public/index.php` sont les deux pièces qui font fonctionner le routage Laravel.
  • `storage` et `bootstrap/cache` doivent être accessibles en écriture par le compte du service web.
  • Les caches Laravel (`config`, `routes`, `views`, `events`) apportent un vrai gain si on les régénère au déploiement.
  • `APP_DEBUG` doit rester à `false` en production, sinon on expose trop d’informations.
  • Le point de santé `/up` sert bien au monitoring, aux load balancers et à Kubernetes.

Comprendre la logique d’une pile Nginx et Laravel

Je vois trop souvent des déploiements qui traitent Nginx comme un simple “serveur de fichiers”. En réalité, son rôle est plus précis: il reçoit la requête, sert les ressources statiques quand c’est possible, puis transmet le reste à PHP-FPM pour que Laravel prenne la main. C’est cette séparation qui rend la pile fiable, rapide et facile à maintenir.

Le point qui compte le plus est le front controller. Laravel attend que les requêtes dynamiques passent par `public/index.php`, pas par la racine du projet. C’est le bon compromis entre sécurité et simplicité: Nginx reste à l’entrée, Laravel gère la logique métier, et aucun fichier de configuration sensible ne se retrouve exposé par erreur.

La documentation Laravel insiste d’ailleurs sur ce point, et je suis d’accord avec cette approche: on construit la configuration autour du dossier `public/`, puis on laisse Nginx faire le tri entre fichiers réels, routes applicatives et code PHP. Une fois ce modèle bien compris, le reste devient beaucoup plus mécanique.

La suite logique, c’est de poser un bloc Nginx propre, lisible et adapté à la production.

Illustration conceptuelle montrant Nginx communiquant avec PHP-FPM, essentiel pour les applications Laravel.

Le bloc Nginx que j’utilise comme base fiable

Je pars d’un `server` minimal, puis j’ajuste le nom de domaine, le socket PHP et les chemins du projet selon l’environnement. L’idée n’est pas de copier un fichier “magique”, mais d’avoir une base cohérente que je peux faire évoluer sans casser le routage.

server {
    listen 80;
    listen [::]:80;
    server_name exemple.fr www.exemple.fr;

    root /var/www/mon-app/public;
    index index.php;
    charset utf-8;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico {
        access_log off;
        log_not_found off;
    }

    location = /robots.txt {
        access_log off;
        log_not_found off;
    }

    error_page 404 /index.php;

    location ~ ^/index\.php(/|$) {
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_hide_header X-Powered-By;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

La documentation NGINX rappelle qu’un `server` définit un serveur virtuel, et que les `location` déterminent comment chaque URI est traitée. Dans ce contexte, trois directives font l’essentiel du travail: `root`, `try_files` et `fastcgi_pass`. Le reste sert surtout à sécuriser et à rendre le comportement plus prévisible.

Directive Rôle Ce que je vérifie
root /var/www/mon-app/public Expose uniquement le dossier public Le projet n’est jamais servi depuis sa racine
try_files $uri $uri/ /index.php?$query_string Fait passer les requêtes non statiques vers Laravel Les routes profondes fonctionnent sans 404 inutile
fastcgi_pass unix:/run/php/php8.3-fpm.sock Relie Nginx à PHP-FPM Le socket ou le port correspond bien à la version PHP installée
deny all sur les fichiers cachés Bloque l’accès aux dotfiles .env et les fichiers système restent inaccessibles
X-Frame-Options et X-Content-Type-Options Ajoutent une base de durcissement Le comportement côté navigateur est moins exposé aux abus classiques

Je laisse volontairement le TLS hors de cet extrait pour garder le noyau lisible. En pratique, vous ajoutez ensuite un bloc HTTPS ou une redirection propre de 80 vers 443, mais le cœur de la configuration ne change pas. Ce qui m’amène au point souvent négligé: les permissions et l’environnement du projet.

Les permissions et l’environnement doivent rester sobres

Laravel a besoin d’écrire dans `bootstrap/cache` et `storage`. Ce n’est pas un détail administratif, c’est une condition de fonctionnement. Les logs, les fichiers temporaires, les caches internes et certaines compilations passent par là, donc le compte du service web doit avoir les droits nécessaires, sans transformer le serveur en zone ouverte.

Je préfère toujours éviter les solutions brutales du type `chmod 777`. Elles donnent l’impression que tout marche, puis elles créent des problèmes de sécurité et de maintenance. Il vaut mieux identifier le vrai utilisateur du service Nginx ou PHP-FPM, puis lui accorder les droits strictement nécessaires sur les répertoires utiles.

  • `storage` pour les logs, les sessions, les fichiers temporaires et certains caches.
  • `bootstrap/cache` pour les caches de configuration et d’autoload.
  • `.env` hors du web root, avec des secrets gérés côté environnement et non exposés par Nginx.

Autre point que je contrôle systématiquement: `APP_DEBUG` doit rester à `false` en production. Après un `config:cache`, Laravel ne recharge plus le `.env` pendant les requêtes, donc il faut que les variables sensibles soient lues proprement dans les fichiers de configuration, pas disséminées partout dans le code. Une fois cette discipline en place, l’optimisation du déploiement devient beaucoup plus fiable.

Les caches Laravel que j’active au déploiement

Dans les petites applications, on sous-estime souvent le coût des allers-retours vers le système de fichiers. Sur un projet avec beaucoup de routes, de vues Blade et de paramètres de configuration, le cache fait une vraie différence. Je ne l’utilise pas comme un réflexe automatique, mais comme une étape de déploiement assumée.

Commande Effet concret Quand l’utiliser
php artisan optimize Regroupe les caches de configuration, événements, routes et vues Au moment du déploiement, sur une application prête pour la production
php artisan config:cache Réduit les lectures répétées des fichiers de configuration Dès que la configuration est stable
php artisan event:cache Mémorise les correspondances événement → listener Quand les événements auto-découverts ne changent pas en continu
php artisan route:cache Accélère l’enregistrement des routes Surtout sur les applications avec des centaines de routes
php artisan view:cache Précompile les vues Blade Pour éviter la compilation à la première requête utile
php artisan optimize:clear Supprime les caches générés Avant un diagnostic ou une correction de déploiement

Le point de vigilance le plus important concerne `config:cache`: une fois la configuration cacheée, les appels à `env()` doivent rester confinés aux fichiers de configuration. Pour `route:cache`, je le fais seulement au déploiement, puis je regénère le cache à chaque modification de route. C’est une habitude simple, mais elle évite des incohérences très pénibles à déboguer.

Quand ces caches sont intégrés au pipeline, le serveur répond plus vite et les écarts entre environnement de test et production diminuent nettement. Il reste alors à surveiller ce qui tourne après la mise en ligne, car un déploiement réussi ne suffit pas à lui seul à garantir la stabilité.

Surveiller ce qui tourne après le déploiement

Je considère le déploiement comme incomplet tant que les services longue durée n’ont pas été pris en compte. Si vous exécutez des queue workers, Laravel Reverb ou Laravel Octane, ils doivent être redémarrés ou rechargés après une nouvelle version de l’application. Sinon, ils continuent parfois à exécuter de vieux fichiers en mémoire, et les bugs ressemblent alors à des fantômes.

Laravel fournit un point de santé natif, généralement exposé sur `/up`. Il renvoie une réponse HTTP 200 si l’application a démarré correctement, et 500 si elle n’a pas booté sans exception. C’est exactement le type de signal que j’aime brancher à un uptime monitor, à un load balancer ou à un système d’orchestration comme Kubernetes.

  • Nginx pour les erreurs de proxy, de routage et d’accès aux fichiers.
  • Les logs Laravel pour les exceptions applicatives et les problèmes métier.
  • Le redémarrage des workers après chaque déploiement de code.
  • Le point `/up` pour savoir si l’application a réellement démarré.

Je garde aussi un œil sur le moniteur de processus quand je ne suis pas sur une plateforme gérée. C’est là que beaucoup de déploiements “fonctionnent” en apparence mais cassent à la première montée de charge, parce qu’aucun service n’est réellement supervisé. Cette logique de surveillance me conduit naturellement à la question du choix d’architecture.

Choisir la pile qui vous évite le plus d’entretien

En 2026, je continue de voir Nginx + PHP-FPM comme le choix le plus robuste pour la majorité des équipes. C’est la pile la plus prévisible, la plus documentée et celle qui s’intègre le plus facilement dans des environnements variés, du VPS classique à l’infrastructure plus structurée. Mais ce n’est pas la seule option raisonnable.

Option Quand elle a du sens Compromis principal
Nginx + PHP-FPM Besoin de contrôle, de stabilité et d’un modèle très connu Plus de pièces à configurer et à superviser
Nginx + FrankenPHP Envie de simplifier la pile et d’explorer un serveur PHP moderne Moins standard dans certaines équipes et certains déploiements
Plateforme gérée Priorité à la vitesse de mise en ligne et à la réduction de la charge ops Moins de liberté fine sur chaque réglage serveur

Je conseille rarement de changer de pile juste par curiosité. Si votre équipe connaît déjà PHP-FPM, que vos déploiements sont stables et que vos besoins sont classiques, rester sur Nginx est souvent le meilleur choix. Si, en revanche, vous cherchez à réduire la complexité opérationnelle ou à intégrer un serveur PHP plus moderne, alors il faut évaluer le coût réel de migration au lieu de suivre la mode.

C’est cette logique de décision qui m’amène au dernier contrôle que je fais toujours avant de déclarer un déploiement propre.

La vérification finale que je fais avant de mettre en ligne

Avant de considérer qu’une installation Nginx pour Laravel est terminée, je passe une checklist courte mais stricte. Elle prend peu de temps, et elle évite la majorité des incidents que l’on retrouve ensuite dans les tickets de production.

  • Le `root` pointe bien vers `public/`.
  • Toutes les requêtes passent correctement par `public/index.php`.
  • Les fichiers cachés sont bloqués, à l’exception de ce qui doit rester public.
  • `storage` et `bootstrap/cache` sont écrivable par le bon compte système.
  • `APP_DEBUG` est désactivé sur l’environnement public.
  • Les caches Laravel ont été régénérés au déploiement.
  • Le point de santé `/up` est surveillé.
  • Les workers et services longue durée ont bien été relancés.

Quand ces huit points tiennent ensemble, la configuration est solide, lisible et facile à maintenir. À ce stade, je ne cherche plus à “faire marcher” Laravel derrière Nginx, je cherche surtout à faire en sorte qu’il reste fiable quand la charge, les déploiements et les petites erreurs humaines s’accumulent.

Questions fréquentes

Pointer Nginx vers `public/` est crucial pour la sécurité. Cela garantit que seuls les fichiers destinés à être publics (comme les assets CSS/JS et l'`index.php` de Laravel) sont accessibles, protégeant ainsi vos fichiers de configuration sensibles et votre code source des accès non autorisés.
`try_files $uri $uri/ /index.php?$query_string` est essentiel. Il permet à Nginx de d'abord chercher un fichier ou un dossier correspondant à l'URI. Si rien n'est trouvé, il redirige la requête vers `index.php`, permettant à Laravel de gérer le routage des requêtes dynamiques via son front controller.
Laravel a besoin d'écrire dans les dossiers `storage` et `bootstrap/cache` pour les logs, les sessions, les caches et la compilation. Accorder les droits d'écriture au compte du service web (sans utiliser `chmod 777`) est vital pour le bon fonctionnement de l'application en production, tout en maintenant la sécurité.
Les caches Laravel réduisent le nombre de lectures de fichiers et les traitements à chaque requête. `config:cache` minimise la lecture des fichiers de configuration, `route:cache` accélère l'enregistrement des routes, et `view:cache` précompile les vues Blade, ce qui se traduit par une application plus rapide et réactive.
Mettre `APP_DEBUG` à `false` en production est une mesure de sécurité fondamentale. Cela empêche l'exposition d'informations sensibles (traces d'erreurs détaillées, variables d'environnement) qui pourraient être exploitées par des attaquants. C'est indispensable pour la robustesse de votre application.

Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

laravel nginx configuration nginx laravel php-fpm optimiser nginx pour laravel nginx laravel erreurs 403 404 502 sécuriser laravel nginx
Autor Léon Weiss
Léon Weiss
Je m'appelle Léon Weiss et j'ai huit ans d'expérience dans le développement web, avec un accent particulier sur JavaScript, le backend, NoSQL et la sécurité. Mon parcours dans ce domaine a commencé par une curiosité insatiable pour la technologie et comment elle façonne notre quotidien. J'aime explorer les défis techniques et aider les lecteurs à comprendre des concepts souvent perçus comme complexes. J'écris principalement sur des sujets liés à la sécurité des applications web et à l'optimisation des bases de données NoSQL, en m'efforçant de rendre ces informations accessibles et pratiques. Je m'engage à fournir des contenus utiles, précis et à jour, en vérifiant mes sources et en comparant les informations pour offrir une perspective claire. Mon objectif est de simplifier des sujets ardus et de suivre les tendances actuelles, afin d'aider mes lecteurs à naviguer dans le paysage en constante évolution du développement web.

Commentaires (0)

Ajouter un commentaire