Test de configuration Nginx : garantir des déploiements fluides avec les commandes clés
Utilisez nginx -t, nginx -T et des habitudes de rechargement sécurisées pour détecter les erreurs de configuration Nginx avant qu'elles n'affectent le trafic.
Test de configuration Nginx : garantir des déploiements fluides avec les commandes clés
Le test de configuration Nginx est l'une de ces habitudes qui semblent trop insignifiantes pour compter jusqu'à ce qu'elle vous évite un rechargement cassé. Un point-virgule manquant, un mauvais chemin d'inclusion ou une directive d'un module que vous ne possédez pas peuvent empêcher Nginx d'accepter une nouvelle configuration. Sur un proxy inverse de production, ce n'est pas une petite erreur.
La commande de base est simple :
sudo nginx -t
Exécutez-la avant chaque rechargement. Exécutez-la après avoir modifié un bloc serveur. Exécutez-la dans l'intégration continue si votre équipe stocke la configuration Nginx dans Git. La commande analyse la configuration et indique si la syntaxe est valide. Elle ne prouve pas que votre logique de routage est correcte, que votre certificat TLS est valide pour chaque nom d'hôte ou que votre application en amont est saine. Elle détecte le type d'erreurs que Nginx peut repérer avant d'appliquer la configuration.
Ce que vérifie nginx -t
nginx -t demande à Nginx de tester la configuration. Il lit le fichier de configuration principal, suit les directives include, analyse les directives et les blocs, et vérifie de nombreux problèmes de fichiers/chemins. Une exécution réussie ressemble généralement à ceci :
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Une exécution échouée pointe vers un fichier et un numéro de ligne :
nginx: [emerg] unexpected "}" in /etc/nginx/conf.d/api.conf:18
nginx: configuration file /etc/nginx/nginx.conf test failed
Le numéro de ligne est l'endroit où l'analyseur a remarqué le problème, pas toujours là où vous avez fait l'erreur. Si Nginx indique qu'un } inattendu apparaît à la ligne 18, vérifiez les lignes au-dessus pour un point-virgule manquant ou un bloc non fermé.
Utilisez sudo lorsque les fichiers de configuration, les fichiers de certificat ou les extraits inclus sont lisibles uniquement par root :
sudo nginx -t
Sans les bonnes permissions, votre test peut échouer même si la syntaxe est correcte.
Utilisez nginx -T lorsque les inclusions rendent la configuration difficile à voir
De nombreuses configurations Nginx répartissent la configuration entre /etc/nginx/nginx.conf, conf.d/*.conf, sites-enabled/* et des extraits partagés. C'est bon pour la maintenabilité, mais cela peut rendre le débogage confus.
nginx -T teste la configuration et affiche la configuration complète analysée sur stdout :
sudo nginx -T
C'est utile lorsque vous devez répondre à des questions comme :
- Quel fichier définit réellement ce bloc serveur ?
- Mon motif
includea-t-il pris un fichier de sauvegarde ? - Cette directive est-elle définie au niveau
http,serveroulocation? - Quel bloc
server_nameen double gagne ?
Soyez prudent en partageant la sortie de nginx -T. Elle peut inclure des chemins de certificats, des noms d'hôte internes, des noms d'amont, des en-têtes ou des commentaires avec un contexte sensible. Pour un ticket, anonymisez avant de coller.
Testez un fichier de configuration non par défaut avec -c
Si vous construisez une configuration dans un chemin de préproduction, utilisez -c :
sudo nginx -t -c /home/deploy/nginx-staging/nginx.conf
Cela indique à Nginx quel fichier de configuration principal tester. Les chemins relatifs dans cette configuration peuvent toujours se comporter différemment selon les paramètres de préfixe, alors gardez les tests de préproduction proches de la disposition de production lorsque c'est possible.
Vous pouvez également inspecter les chemins de compilation et les modules avec :
nginx -V
La sortie va vers stderr sur de nombreux systèmes, ce qui surprend les gens lors de la redirection de sortie. Elle montre la version de Nginx et les options de construction, y compris le support des modules et les chemins par défaut. Cela compte lorsqu'une configuration utilise des directives de modules tels que http_v2, realip, stub_status ou le proxy de flux.
Rechargez, ne redémarrez pas à la légère
Une fois le test réussi, rechargez Nginx :
sudo systemctl reload nginx
Un rechargement demande au processus maître de lire la nouvelle configuration et de démarrer de nouveaux workers pendant que les anciens workers terminent les requêtes existantes. C'est le chemin normal pour les modifications de configuration.
Un redémarrage arrête et démarre le service :
sudo systemctl restart nginx
Utilisez le redémarrage lorsque vous en avez réellement besoin, par exemple après des changements de paquets ou un problème d'état du service. Pour les modifications de configuration ordinaires, le rechargement est moins perturbateur.
Certains fichiers unit systemd exécutent un test de configuration dans le cadre du rechargement. Ne comptez pas là-dessus comme votre seul filet de sécurité. Exécutez nginx -t vous-même d'abord pour voir l'échec avant de toucher au service en cours d'exécution.
La commande de signal native Nginx est également courante :
sudo nginx -s reload
Sur les serveurs gérés par systemd, je préfère généralement systemctl reload nginx car il maintient l'état du service et les journaux dans la même couche de gestion.
Un flux de travail d'édition sécurisé
Pour un changement normal de bloc serveur, utilisez ce rythme :
sudo cp /etc/nginx/conf.d/api.conf /etc/nginx/conf.d/api.conf.bak.$(date +%Y%m%d%H%M%S)
sudoedit /etc/nginx/conf.d/api.conf
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl status nginx --no-pager
Si votre configuration est dans Git, validez le changement au lieu de conserver des fichiers de sauvegarde aléatoires pour toujours. La commande de sauvegarde ci-dessus est utile pour les petits serveurs non gérés, pas un remplacement pour le contrôle de version.
Après le rechargement, testez la route réelle :
curl -I https://example.com/api/health
curl -I -H 'Host: example.com' http://127.0.0.1/
nginx -t peut vous dire que la configuration s'analyse. curl vous dit si le site se comporte comme vous le souhaitiez.
Messages d'échec courants et ce qu'ils signifient généralement
Un point-virgule manquant ressemble souvent à ceci :
nginx: [emerg] invalid number of arguments in "proxy_set_header" directive in /etc/nginx/conf.d/app.conf:22
Vérifiez la directive à cette ligne et celle d'avant. Les directives Nginx se terminent généralement par ;, tandis que les blocs se terminent par { ... }.
Un mauvais chemin d'inclusion ressemble à ceci :
nginx: [emerg] open() "/etc/nginx/snippets/security-headers.conf" failed (2: No such file or directory)
Soit le chemin du fichier est erroné, l'extrait n'a pas été déployé, ou le motif d'inclusion est spécifique à l'environnement.
Un problème de permission peut ressembler à ceci :
nginx: [emerg] cannot load certificate "/etc/letsencrypt/live/example.com/fullchain.pem": BIO_new_file() failed
Le fichier peut être manquant, le lien symbolique peut être cassé, ou l'utilisateur exécutant le test ne peut pas le lire. Les scripts de renouvellement et de déploiement de certificats sont des endroits courants où cela se produit.
Une directive inconnue signifie l'une des trois choses : faute de frappe, mauvais contexte ou module manquant.
nginx: [emerg] unknown directive "proxy_cache_purge"
Peut-être que le nom de la directive est erroné. Peut-être qu'il appartient à un module différent. Peut-être que votre build Nginx de production n'inclut pas le module tiers qui existait en préproduction. Vérifiez nginx -V avant de supposer que la configuration est portable.
Un nom de serveur en double ou conflictuel peut apparaître comme un avertissement plutôt qu'un échec dur :
nginx: [warn] conflicting server name "example.com" on 0.0.0.0:80, ignored
N'ignorez pas les avertissements simplement parce que la ligne finale indique que le test a réussi. Un avertissement peut signifier que Nginx n'utilisera pas le bloc serveur que vous pensez qu'il utilisera.
Test dans l'intégration continue
Si la configuration Nginx vit dans un dépôt, testez-la avant le déploiement. Une simple vérification basée sur un conteneur peut monter la configuration dans une image Nginx et exécuter :
nginx -t -c /etc/nginx/nginx.conf
La partie difficile est de faire correspondre les chemins de production. Si votre configuration fait référence à /etc/letsencrypt, les tests locaux ont besoin de fichiers factices ou d'une configuration spécifique au test. Si elle fait référence à des noms d'hôte en amont, le test de syntaxe n'a pas besoin que l'amont soit actif, mais les fichiers inclus et les fichiers de certificat doivent exister.
Pour les équipes avec de nombreux sites, ajoutez une étape de pré-déploiement qui exécute nginx -T et stocke la sortie nettoyée comme un artefact. Lorsqu'un rechargement se comporte étrangement, vous pouvez comparer la configuration rendue du dernier bon déploiement à celle actuelle.
Ce que le test de configuration ne peut pas attraper
nginx -t ne vous dira pas que votre nouveau bloc location est masqué par une autre expression régulière de localisation. Il ne saura pas que votre application en amont renvoie des 500. Il ne prouvera pas qu'une chaîne de redirection est sensée ou qu'une règle de cache est sûre.
Pour cela, ajoutez des vérifications de comportement :
curl -I https://example.com/
curl -I https://example.com/old-path
curl -sS https://example.com/api/health
Pour les modifications TLS, vérifiez le certificat du point de vue du client :
openssl s_client -connect example.com:443 -servername example.com </dev/null
Pour les modifications de proxy inverse, surveillez les journaux pendant et après le rechargement :
sudo tail -f /var/log/nginx/error.log /var/log/nginx/access.log
Le test de configuration Nginx n'est pas une stratégie de déploiement complète, mais c'est la porte que chaque stratégie devrait inclure. Utilisez nginx -t pour la syntaxe, nginx -T pour le débogage de la configuration rendue, nginx -V pour les détails de construction, et systemctl reload nginx pour les modifications normales. Ensuite, vérifiez le comportement avec des requêtes réelles.