Mettre à jour un service derrière Nginx tient en une règle : on démarre la nouvelle génération à côté de l'ancienne, on vérifie qu'elle répond, on bascule par un reload, et on garde de quoi revenir. Un reload qui réussit ne prouve ni que le binaire a changé, ni que le bon certificat est publié, ni que le service reviendra après un redémarrage de la machine. Cette leçon s'adresse à une personne qui sait recharger Nginx et qui doit maintenant livrer, mesurer et restaurer. Elle enseigne ce que chaque geste remplace réellement, ce qu'il faut sauvegarder avant, et comment prouver le résultat depuis le client.
Un mot de vocabulaire sert dans toute la leçon : une génération est une version du service, déployée avec son propre port et son propre certificat. La bascule est l'instant où Nginx cesse d'envoyer les nouvelles requêtes à l'ancienne génération pour les envoyer à la nouvelle, et le retour arrière est la bascule inverse.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »La leçon va du geste le plus léger, le reload, au plus lourd, la perte de la machine.
- Distinguer un reload de configuration, un remplacement du binaire et un redémarrage de l'hôte.
- Livrer une nouvelle génération du service sans interrompre le trafic court.
- Mesurer ce que devient une connexion longue pendant la bascule.
- Sauvegarder ce qui permet de revenir, puis restaurer avec le certificat de la bonne génération.
- Prouver que le service redémarre seul avec la machine.
Prérequis
Section intitulée « Prérequis »Vous recevez déjà du trafic HTTPS derrière Nginx et vous savez le valider et le recharger.
nginx -t,nginx -Tetreload: Installer Nginx.- Un certificat servi par Nginx et son renouvellement par reload : Nginx TLS.
- Le diagnostic d'une panne après changement : Diagnostiquer Nginx.
- Lire une unité systemd : Les services systemd.
- Une machine Debian 13 avec
sudo, où Nginx 1.31.8 est installé depuis le dépôt de l'éditeur (nginx.org) à la version épinglée par le lab.
Reload, mise à jour du binaire, perte de l'hôte : que change chaque geste ?
Section intitulée « Reload, mise à jour du binaire, perte de l'hôte : que change chaque geste ? »Un reload relit la configuration, un remplacement du binaire change le programme qui s'exécute, et le redémarrage de la machine (la forme la plus courante de perte de l'hôte) relance tout depuis le disque : ce sont trois événements différents, et aucun ne dispense des deux autres. Les confondre est la source de la plupart des mises à jour qui « passent » sans rien changer.
| Geste | Ce qui change | Ce qui ne change pas |
|---|---|---|
systemctl reload nginx | Configuration, certificats lus au chargement | Le binaire en mémoire, le processus maître |
| Remplacement du binaire | Le programme et ses modules | La configuration (elle est conservée) |
| Redémarrage de la machine | Tout est relancé depuis le disque | Rien en mémoire |
Le tableau se lit de gauche à droite : la colonne du milieu dit ce qu'on obtient, la dernière ce qui reste inchangé et qu'il faut donc traiter à part. Après une mise à jour du paquet, le processus peut encore exécuter l'ancien binaire : le lien /proc/<PID>/exe du maître affiche alors (deleted) quand le fichier a été remplacé (c'est un comportement du noyau Linux, décrit dans la page de manuel proc_pid_exe(5), pas une fonction de Nginx), et nginx -v donne la version installée, pas celle qui tourne. La mise à jour à chaud du binaire existe (elle passe par le signal USR2 envoyé au maître, décrit dans la documentation de nginx.org), mais selon les scripts du paquet, une montée de version peut aussi relancer le service : prévoyez-la comme une coupure possible et mesurez-la. Le dépôt de l'éditeur publie environ une fois par mois sur la branche mainline : monter de version est un geste courant, qui se prépare par la recette ci-dessous plutôt que par l'improvisation.
Enfin, deux workers (les processus qui traitent les requêtes, sous la conduite du maître) ne sont pas deux domaines de panne, c'est-à-dire deux éléments dont l'un peut tomber sans entraîner l'autre. Ils partagent le même maître, la même machine, la même configuration : si le disque, la machine ou la configuration tombe, ils tombent ensemble. Augmenter le nombre de workers améliore le parallélisme, pas la disponibilité.
Que vérifier avant de changer de version ?
Section intitulée « Que vérifier avant de changer de version ? »On vérifie la version cible, les modules, les certificats et les directives utilisées avant de toucher au service, parce qu'une directive absente de la version cible fait échouer la validation ou, pire, se comporte autrement. Le lab installe Nginx 1.31.8 depuis le dépôt de l'éditeur, à la version épinglée : lisez les notes de la version cible avant de monter, car une directive dépréciée reste acceptée sans être la forme à écrire, par exemple le paramètre http2 de listen, remplacé par la directive http2 on; que détaille la leçon Nginx flux longs. Une directive inconnue de la version cible est refusée par nginx -t, et c'est heureux : le refus arrive avant la coupure.
Quatre contrôles servent de recette avant et après chaque changement.
nginx -vetnginx -Vdonnent la version et les options de compilation, dont les modules présents.sudo nginx -tvalide la syntaxe, etsudo nginx -Taffiche la configuration que le processus lira vraiment.- Les certificats dont
nginx -Tdonne les chemins (ssl_certificate,ssl_certificate_key) : leurs dates et leur empreinte se lisent avecopenssl x509 -noout -dates -fingerprint -sha256 -in <fichier>. - La recette métier : une requête par route, depuis un client, avec le contenu attendu et non seulement un code
200.
Rejouez cette recette avant pour avoir un point de comparaison, puis après : sans mesure de départ, on ne sait pas ce qui a changé.
Que faut-il sauvegarder pour pouvoir revenir ?
Section intitulée « Que faut-il sauvegarder pour pouvoir revenir ? »On sauvegarde la configuration complète, les certificats et leurs clés avec leurs droits, les surcharges d'unité systemd et la version du paquet : sans elles, un retour arrière devient une reconstruction. Avec le paquet de nginx.org, la configuration vit sous /etc/nginx/ : le fichier principal nginx.conf et le répertoire conf.d/, dont nginx.conf inclut les fichiers *.conf. Les certificats et clés, eux, peuvent se trouver n'importe où : seul nginx -T donne leurs chemins réels. Une sauvegarde qui oublie la clé privée ne restaure rien.
# La liste des fichiers de certificat réellement utiliséssudo nginx -T 2>/dev/null | grep -E 'ssl_certificate(_key)?[[:space:]]'
# Archive de la configuration, droits conservés (-p), vers un répertoire de votre choixsudo tar -cpzf <répertoire-de-sauvegarde>/nginx-etc.tar.gz /etc/nginx
# Version installée du paquet, à noter pour pouvoir y revenirapt-cache policy nginxLa première commande donne les fichiers de certificat à ajouter à l'archive ; adaptez <répertoire-de-sauvegarde>, qui doit se trouver hors de /etc/nginx. L'option -p garde les modes, ce qui compte pour une clé en 0600. apt-cache policy affiche la version installée et les versions disponibles : notez la première, car revenir à une version de paquet n'est possible que si le dépôt la propose encore. Si une surcharge existe sous /etc/systemd/system/nginx.service.d/, ajoutez-la : elle modifie la façon dont le service démarre.
Une dernière précaution porte sur les fichiers de configuration modifiés à la main : lors d'une mise à jour du paquet, dpkg (l'outil qui installe les paquets sous Debian) peut demander s'il faut conserver votre version ou prendre celle du paquet (selon les options d'APT, la question peut ne pas être posée). Si elle l'est, gardez la vôtre, puis comparez avec diff ; la nouvelle version de référence reste consultable à côté.
Comment livrer une nouvelle génération sans couper le trafic ?
Section intitulée « Comment livrer une nouvelle génération sans couper le trafic ? »On démarre la nouvelle génération sur son propre port, on attend qu'elle réponde, on fait pointer le proxy dessus, on valide, puis on recharge : l'ancienne n'est retirée qu'à la livraison suivante. Chaque génération a son port et son certificat, donc les deux peuvent tourner en même temps, et c'est ce qui rend atteignable une bascule sans erreur. Arrêter l'ancienne avant de démarrer la nouvelle ouvre une fenêtre que rien ne referme.
Suivez l'ordre des flèches : la nouvelle génération est prête avant que le proxy ne la désigne, et le reload est la dernière étape, pas la première. Le mécanisme du reload (maître conservé, nouveaux workers, anciens workers qui terminent) est décrit dans Installer Nginx. Le geste complet s'écrit en un exécutable rejouable (livrer <version> dans le lab), qui rend la main quand la nouvelle génération est réellement servie, et qui est idempotent : le relancer avec la même version donne le même état final et ne casse rien.
Deux valeurs lues par le client, jamais celles du disque, disent si la livraison a réussi. La version servie : curl -sk --resolve <nom>:443:<IP> https://<nom>/version. L'empreinte du certificat publié, lue dans la poignée de main :
echo | openssl s_client -connect <IP>:443 -servername <nom> 2>/dev/null \ | openssl x509 -noout -fingerprint -sha256La commande affiche une ligne sha256 Fingerprint= suivie de l'empreinte : comparez-la à celle de la génération attendue. Dès que deux générations portent le même nom de service, seule l'empreinte dit laquelle est publiée.
Ce que le client lit dépend de la façon dont Nginx lit le certificat. Avec un chemin fixe dans ssl_certificate, il le lit au chargement de la configuration : un changement de fichier n'est donc visible qu'après le reload. Seul un chemin construit avec des variables (possible depuis la 1.15.9) est relu à chaque poignée de main, et ce n'est pas le cas dans le lab.
Que devient une connexion longue pendant un reload ?
Section intitulée « Que devient une connexion longue pendant un reload ? »Une connexion déjà établie reste servie par les anciens workers jusqu'à sa fin ; seules les nouvelles connexions vont aux nouveaux workers. Un reload ne coupe donc pas un flux long (téléchargement, flux d'événements, WebSocket), tandis qu'un restart coupe toutes les connexions. La différence ne se voit que sur un flux long : sur du trafic court, les deux ressemblent à une réussite.
Deux limites se mesurent plutôt qu'elles ne se supposent. D'abord, un ancien worker qui garde un flux ouvert reste en vie : ps le montre avec la mention worker process is shutting down, et la directive worker_shutdown_timeout (apparue en 1.11.11) permet de borner ce temps : à l'échéance, Nginx tente de fermer les connexions encore ouvertes, ce qui coupe les flux qui le dépassent. La documentation n'en donne aucune valeur par défaut : ne supposez pas de limite, et un worker peut rester tant qu'un flux reste ouvert. Ensuite, recharger le proxy ne protège pas contre l'arrêt du backend : si la livraison arrête l'ancienne génération, les flux qu'elle servait sont coupés quand même. C'est pour cela que l'ancienne génération reste active jusqu'à la livraison suivante. Pour les flux eux-mêmes, voir Nginx flux longs.
Mesurez avec trois relevés pendant la livraison : le nombre de requêtes courtes en échec sur une série continue, l'état du flux long ouvert avant la bascule (continue-t-il de recevoir ?), et le temps pendant lequel d'anciens workers subsistent. Écrivez ces résultats et votre conclusion dans un court journal de livraison. Une série sans échec ne prouve pas qu'une absence de coupure est garantie partout : elle décrit cette livraison, sur cette machine, avec ce trafic.
Comment revenir en arrière avec le bon certificat ?
Section intitulée « Comment revenir en arrière avec le bon certificat ? »Un retour arrière est une livraison à l'envers : il remet le code, la configuration et le certificat de la génération précédente, et il a besoin de savoir d'où il vient. Le piège est de ne ramener que le code. Si les deux générations portent le même nom de service, un retour qui oublie le certificat n'a l'air de rien : le service répond, le nom est bon, et seule l'empreinte dit que le certificat est celui de la génération qu'on vient de retirer.
La mémoire de la génération précédente doit être écrite à un endroit qui survit au redémarrage. Les répertoires /run et /tmp sont vidés au démarrage ; /var/lib ne l'est pas : on y crée donc un sous-répertoire pour cette mémoire. Un revenir (l'exécutable de retour arrière du lab) qui lirait son état dans /tmp fonctionnerait jusqu'au premier reboot, puis ne saurait plus où revenir.
Pour restaurer la configuration depuis l'archive faite plus haut, extrayez-la, puis validez avant de recharger, jamais l'inverse : sudo tar -xpzf <archive> -C /, puis sudo nginx -t && sudo systemctl reload nginx. Pour restaurer le paquet, installez la version notée (sudo apt install nginx=<version>, si le dépôt la propose encore ; lisez la liste des paquets qu'apt propose de modifier avant de confirmer), puis relancez la recette complète : version, modules, certificat, routes. Après un retour, vérifiez la version servie et l'empreinte, pas la seule absence d'erreur.
Comment prouver que tout survit à un redémarrage de la machine ?
Section intitulée « Comment prouver que tout survit à un redémarrage de la machine ? »Un service livré n'est pas un service lancé : il doit revenir seul après un redémarrage, sans une commande de plus. systemctl enable programme le démarrage au boot, systemctl start le lance maintenant : les deux sont distincts, et un service seulement démarré disparaît au premier reboot. Vérifiez les deux états pour Nginx et pour chaque service de la pile :
systemctl is-enabled nginxsystemctl is-active nginxLa première commande doit répondre enabled, la seconde active. Pour une pile qui compte une unité par génération, une unité modèle (unite@instance.service) évite de dupliquer les fichiers : l'identifiant d'instance y est disponible sous %i. Le test final se fait en redémarrant la machine, puis en rejouant la recette sans rien toucher. Il ne se remplace pas par un systemctl restart : seul un vrai redémarrage vérifie l'ordre de démarrage, les droits et les dossiers vidés au boot.
Quelles erreurs fait-on le plus souvent ?
Section intitulée « Quelles erreurs fait-on le plus souvent ? »Cinq erreurs reviennent, et chacune a un contrôle qui la rend visible.
- Prendre un reload réussi pour une mise à jour du binaire. Comparez la version installée et la version qui tourne.
- Croire que deux workers donnent de la disponibilité. Ils partagent la machine, le maître et la configuration.
- Arrêter l'ancienne génération avant de démarrer la nouvelle. La fenêtre d'indisponibilité n'a rien qui la ferme.
- Revenir sans le certificat. Comparez l'empreinte, pas le nom.
- Stocker l'état du retour arrière dans
/tmp. Il disparaît au reboot.
Mettre en pratique
Section intitulée « Mettre en pratique »Dans le lab, un service est publié en TLS derrière Nginx dans sa génération 1.4.2, et une seconde génération, 1.5.0, est déjà sur le disque, chacune avec son port et son certificat. Vous écrivez deux exécutables, livrer <version> et revenir, dans le langage de votre choix, et vous tenez un journal de vos mesures. La validation joue vos exécutables dans l'ordre du plan et mesure entre chaque appel : elle lit la version servie et l'empreinte du certificat depuis le client, vérifie qu'au plus une requête échoue sur une sonde continue pendant la bascule, que le flux long ouvert avant la bascule continue de recevoir après, que le journal existe et parle du flux long, que revenir ramène 1.4.2 avec son certificat, et que la recette passe après un redémarrage de la machine sans intervention.
À retenir
Section intitulée « À retenir »Une mise à jour se prouve depuis le client, jamais depuis le disque.
- Un reload relit la configuration ; il ne remplace pas le binaire et ne protège pas du redémarrage de la machine.
- Le dépôt de l'éditeur publie une version mainline environ chaque mois : une montée de version se prépare par une recette,
nginx -trefuse ce que la version cible ne connaît plus. - Avant de changer :
nginx -v,nginx -t,nginx -T, les certificats et une recette par route. - Sauvegardez
/etc/nginxavec ses droits, les certificats et clés dontnginx -Tdonne les chemins, les surcharges d'unité et la version du paquet. - Livrez en démarrant la nouvelle génération à côté, en attendant sa réponse, puis en rechargeant ; l'ancienne reste jusqu'à la livraison suivante.
- Un flux long survit à un reload mais pas à l'arrêt de son backend ; mesurez-le, ne le supposez pas.
- Un retour arrière ramène le code et le certificat, et garde sa mémoire sous
/var/lib, pas sous/tmp. enablen'est passtart: seul un vrai redémarrage de la machine prouve que le service revient seul.
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Continuer le cours : Nginx : synthèse, recettes et aide-mémoire
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications