E-NO
Dépannage Nginx 10 min de lecture

Dépannage Nginx : Guide pratique avec exemples

calendar_today Publié : 2026-07-09
update Dernière mise à jour : 2026-07-09
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Dépannage Nginx : Guide pratique avec exemples ».

Nginx est un reverse proxy et un serveur web rapides et flexibles, mais les problèmes en production peuvent être délicats lorsque les symptômes se chevauchent. Ce guide vous donne un flux de travail de dépannage pratique avec des commandes sûres, des astuces de lecture des logs et des mini runbooks pour les pannes courantes. Vous serez en mesure de :

  • Identifier ce qui a cassé et où : Nginx, le réseau ou l'application upstream.
  • Lire et filtrer les logs d'accès et d'erreur pour voir la cause et l'effet.
  • Valider la configuration sans risque avant de recharger.
  • Corriger les erreurs courantes comme 502, 504, 413, 403, 404 et les échecs de handshake TLS.
  • Appliquer la même approche sur hôtes Linux, dans Docker et avec Kubernetes Ingress.

Des exemples concrets sont inclus pour vous permettre de pratiquer localement et de réduire le temps d'indisponibilité quand c'est critique.

Vue d'ensemble du flux de travail

Utilisez cette boucle en production et gardez vos étapes petites. Chaque étape inclut des commandes pratiques et des astuces.

  1. Confirmer le symptôme
  • Capturer l'erreur exacte et le chemin d'URL. Exemple : 502 sur GET /api.
  • Reproduire avec curl pour éviter le bruit côté client :
     curl -iv http://example.com/api
     curl -kiv https://example.com/secure
  1. Vérifier le processus et les ports
  • Nginx tourne-t-il ?
     systemctl status nginx
     # ou
     service nginx status
  • Écoute-t-il là où vous l'attendez ?
     ss -tulpn | grep -E ':80|:443'
  • Qu'est-ce qui utilise le port si ce n'est pas Nginx ?
     fuser -v 80/tcp 443/tcp
     lsof -i :80 -i :443

Emplacements par défaut :

  1. Inspecter les logs rapidement

Suivre et filtrer les erreurs récentes :

  • /var/log/nginx/error.log
  • /var/log/nginx/access.log
   tail -Fn200 /var/log/nginx/error.log
   grep -iE 'error|crit|alert' /var/log/nginx/error.log
   tail -Fn200 /var/log/nginx/access.log
   awk '{print $1, $4, $6, $7, $9, $10}' /var/log/nginx/access.log

Astuce : augmenter temporairement le détail du log d'erreur en environnement de test :

   error_log /var/log/nginx/error.log info;
   # ou debug si compilé avec debug

Toujours tester avant de recharger :

  1. Valider la configuration sans risque
   grep -RIn 'error|warn' /etc/nginx/*.conf /etc/nginx/conf.d || true
   nginx -t

Sauvegarder avant les changements :

   cp -a /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%F-%H%M)

Si vous utilisez proxy_pass http://app:3000, testez la cible directement depuis l'hôte Nginx :

  1. Sonner l'upstream et le réseau
   curl -iv http://127.0.0.1:3000/health || curl -iv http://app:3000/health

Dans Docker, assurez-vous que le nom résout et que le port est accessible depuis le conteneur Nginx :

   docker exec -it nginx sh -lc 'getent hosts app && curl -sS http://app:3000/health'

Afficher la chaîne de certificats et la gestion SNI :

  1. Vérifications TLS de bon sens
   openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates

Tester à nouveau, puis recharger sans couper les connexions :

  1. Appliquer les corrections ciblées via les mini runbooks (ci-dessous)
  2. Recharger sans risque et de façon atomique
   nginx -t && systemctl reload nginx || service nginx reload
  1. Vérifier et surveiller les régressions
   curl -Is http://example.com/ | head -n1
   curl -Is https://example.com/ | head -n1
   for p in / /health /api/version; do curl -sSfo /dev/null -w '%{http_code} %{url_effective}\n' http://example.com"$p\); done
  1. Durcir pour éviter la récurrence
  • Ajouter des endpoints de santé sur les upstreams.
  • Ajuster timeouts et buffers selon le trafic observé.
  • Centraliser les logs ; ajouter des alertes sur les pics de 5xx et 499.

Mini runbooks : Erreurs Nginx courantes et correctifs

Chaque sous-section donne les symptômes, les vérifications de cause racine et les correctifs sûrs.

502 Bad Gateway (proxy vers l'app)

Symptômes : 502 sur les routes proxifiées. Le log d'erreur peut montrer upstream connect ou prematurely closed connection.

Vérifications :

# L'upstream est-il up ?
curl -iv http://127.0.0.1:3000/health

# Résolution DNS si un nom est utilisé dans proxy_pass
getent hosts app || dig +short app

# Exemple socket ou PHP-FPM
ls -l /run/php/php-fpm.sock && ss -xl | grep php-fpm

Pièges de config et correctifs :

location /api/ {
    proxy_pass http://127.0.0.1:3000/; # noter le comportement du slash final
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_connect_timeout 5s;
    proxy_read_timeout 60s;
}
  • Si le DNS Docker est utilisé, ajouter un resolver dans http{} quand on proxy vers des noms qui changent :
  resolver 127.0.0.11 valid=30s; # DNS embarqué Docker
  • Pour PHP-FPM :
  location ~ \.php$ {
      fastcgi_pass unix:/run/php/php-fpm.sock; # ou 127.0.0.1:9000
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }

504 Gateway Timeout

Symptômes : Attentes longues se terminant en 504.

Vérifications et correctifs :

# Augmenter les timeouts pour correspondre au comportement upstream
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# Garder l'upstream en vie pour réduire la surcharge de handshake
upstream app {
    server 127.0.0.1:3000;
    keepalive 16;
}

Revoir aussi les logs upstream pour requêtes lentes ou pauses GC.

413 Request Entity Too Large

Symptômes : Les uploads échouent ; le log d'erreur montre client intended to send too large body.

Correctif :

# Placer dans http, server ou location selon le besoin
client_max_body_size 50m;

Recharger et retester uniquement le chemin d'upload.

404 Not Found et 403 Forbidden

Causes fréquentes du 404 :

  • Mauvais mapping root vs alias.
  • try_files mal ordonné.
  • Surprises de priorité des locations.

Causes fréquentes du 403 :

  • Fichier index manquant.
  • Permissions fichiers ou contexte SELinux.

Patterns de correction :

server {
    root /var/www/site/public;
    index index.html index.htm;

    location /images/ {
        alias /mnt/media/img/; # alias remplace root pour ce bloc
        autoindex off;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Permissions Linux et SELinux :

# S'assurer que l'utilisateur nginx peut lire les répertoires
namei -l /var/www/site/public/index.html

# Réparation contexte SELinux (sur distros avec SELinux)
sudo restorecon -R /var/www/site || sudo chcon -R -t httpd_sys_content_t /var/www/site

Échecs de handshake TLS

Symptômes : curl -k fonctionne mais les navigateurs échouent ; le log d'erreur montre des erreurs SSL ou pas de cipher partagé.

Patterns de correction :

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    add_header Strict-Transport-Security 'max-age=31536000' always;
}

Vérifier la chaîne et le SNI :

openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null | openssl x509 -noout -subject -issuer -dates

Si vous voyez le mauvais certificat, vérifier le matching server_name et qu'un seul default_server gère le 443.

Problèmes d'en-têtes 400/431 et 499 Client Closed Request

  • En-têtes volumineux : augmenter les buffers.
  large_client_header_buffers 4 16k;
  underscores_in_headers on; # si vos clients envoient des underscores
  • 499 indique que le client a fermé la connexion prématurément. Vérifier la latence upstream et les timeouts client ; réduire le temps de réponse, garder les corps petits.

Problèmes WebSocket et HTTP Upgrade

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

location /ws/ {
    proxy_pass http://127.0.0.1:8080/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
}

Échecs de rechargement ou de démarrage

Symptômes : nginx -t échoue ou le rechargement ne fait rien.

Vérifications :

nginx -t
journalctl -u nginx -n 100 --no-pager
# Erreurs courantes : listen dupliqué, directive inconnue, mauvais include

Conflits de ports :

ss -tulpn | grep ':80\|:443' || true
# Arrêter l'autre processus ou changer les ports d'écoute Nginx

Spécificités Docker, Kubernetes Ingress et Linux

Docker

  • Monter la config à /etc/nginx et tester à l'intérieur du conteneur :
  docker exec -it nginx sh -lc 'nginx -t && nginx -V && ss -tulpn'
  • S'assurer que les noms dans proxy_pass résolvent à l'intérieur du conteneur. Envisager d'ajouter :
  resolver 127.0.0.11 valid=30s;

Kubernetes Ingress (NGINX Controller)

  • Inspector les logs et événements du contrôleur :
  kubectl logs -n ingress-nginx deploy/ingress-nginx-controller --tail=200
  kubectl describe ingress your-ingress -n your-namespace
  • Paramètres courants : timeouts (annotations), taille du corps, en-têtes proxy. S'assurer que votre Service pointe vers des Pods sains et que les readinessProbes réussissent.

Bases Linux

  • Pare-feu : autoriser 80 et 443 (ufw, firewalld, iptables).
  • SELinux : vérifier les contextes pour le contenu et les certificats.
  • Systemd : privilégier reload plutôt que restart pour les changements de config.

Plan pilote local

Commencez avec un petit pilote que vous pouvez inspecter localement. Gardez une portée étroite et mesurable.

Objectifs

  • Servir du contenu statique à / et proxy /api vers une app démo sur 127.0.0.1:9000.
  • Exercer les cas 502, 413 et TLS à la demande.
  • Pratiquer les rechargements sûrs avec zéro requête échouée pendant le changement.

Installation

  1. Upstream démo
   # App démo simple (exemple Python)
   python3 -m http.server 9000 --bind 127.0.0.1 &
  1. Config Nginx
   # /etc/nginx/conf.d/pilot.conf
   server {
       listen 80;
       server_name localhost;
       root /usr/share/nginx/html;
       index index.html;

       location /api/ {
           proxy_pass http://127.0.0.1:9000/;
           proxy_set_header Host $host;
           proxy_set_header X-Forwarded-For $remote_addr;
           proxy_set_header X-Forwarded-Proto $scheme;
           client_max_body_size 5m; # ajuster dans les tests
       }
   }
  1. Valider et recharger
   nginx -t && systemctl reload nginx || service nginx reload

Cas de test

  • Chemin nominal :
  curl -sS -w '%{http_code}\n' -o /dev/null http://localhost/
  curl -sS -w '%{http_code}\n' -o /dev/null http://localhost/api/
  • Drill 502 : arrêter l'upstream et confirmer le comportement Nginx, puis restaurer.
  pkill -f 'http.server 9000' || true
  curl -sS -v http://localhost/api/
  python3 -m http.server 9000 --bind 127.0.0.1 &
  • Drill 413 : uploader un fichier plus gros que client_max_body_size et surveiller error.log.
  head -c 10M </dev/urandom > big.bin
  curl -sS -F [email protected] http://localhost/api/upload
  • Drill TLS (optionnel) : ajouter un certificat auto-signé et un server 443, puis vérifier avec openssl.

Critères de succès

  • Réponses 200 pour / et /api avec l'upstream up.
  • 502 apparaît quand l'upstream est down ; disparaît quand il revient.
  • 413 survient pour corps trop gros ; succès après augmentation de client_max_body_size.
  • Aucune erreur dans nginx -t et rechargements propres.
  • error.log montre clairement chaque cas de test.

Rollback

cp -a /etc/nginx/nginx.conf.bak.* /etc/nginx/nginx.conf 2>/dev/null || true
# Ou déplacer pilot.conf et recharger
mv /etc/nginx/conf.d/pilot.conf /etc/nginx/conf.d/pilot.conf.off
nginx -t && systemctl reload nginx || service nginx reload

Conclusion

Utilisez la boucle : confirmer le symptôme, vérifier processus et ports, lire les logs, valider la config, tester l'upstream et le TLS, appliquer un correctif ciblé, recharger sans risque, et vérifier. Pratiquez avec le pilote local jusqu'à ce que chaque mini runbook devienne routinier. Appliquez ensuite les mêmes patterns à Docker et Kubernetes Ingress : vérifier la résolution de noms, les endpoints de santé, les timeouts et les en-têtes. Gardez les changements petits, fiez-vous aux logs et à curl pour un retour rapide, et documentez les commandes exactes qui ont marché pour que votre équipe puisse les reproduire en confiance.

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO