Niveau 🟡 intermédiaire
Durée estimée : 20 min · Prérequis : Évaluer un service avant de l'installer
Nginx Proxy Manager (NPM), c'est le standard téléphonique vu en
M2, mais avec un tableau de bord graphique pour brancher les
lignes plutôt qu'un fichier de configuration à éditer à la main — le même principe, rendu
accessible sans écrire une seule ligne de configuration bas niveau.
Ce que NPM apporte concrètement : une interface web pour créer des « Proxy Hosts » — des
règles qui associent un nom de domaine à un service interne, avec gestion du certificat TLS
intégrée (upload d'un certificat existant, ou génération Let's Encrypt pour un domaine exposé
publiquement). Alternative citée dans l'écosystème : Traefik, plus orienté configuration
déclarative et intégration automatique avec Docker — un choix d'architecture différent, pas
comparé en détail ici.
Premier démarrage : le piège du compte administrateur. Les versions récentes de NPM ne
pré-remplissent plus de compte par défaut : le tout premier compte administrateur se crée via
une requête à l'API, non authentifiée tant qu'aucun utilisateur n'existe encore. Une fenêtre
de vulnérabilité brève, mais réelle, entre le démarrage du conteneur et la création de ce
premier compte — à combler sans délai.
Créer un Proxy Host, les champs essentiels : le nom de domaine demandé (.internal,
vu en M2), l'adresse de destination (le nom du conteneur cible sur le
réseau npm_proxy partagé, jamais son adresse IP directe), le port interne du service visé,
et le certificat TLS à associer (généré ou importé).
⚠️ Le piège du hairpin NAT, concrètement. Configurer un Proxy Host pour qu'il pointe vers
l'IP externe de la machine (plutôt que vers127.0.0.1ou le nom du conteneur cible) peut
provoquer une erreur504— le trafic part de NPM, tente de ressortir vers l'IP externe, doit
alors « faire demi-tour » vers un conteneur de cette même machine. Le hairpin NAT n'est donc pas
qu'une notion théorique de M2 : c'est une erreur504bien réelle et reproductible à la
première mauvaise configuration.
🧪 Concrètement, sur notre exemple : NPM est déployé en stack, via l'API Portainer, avec un
tag figé (jamaislatest). Le premier compte a été créé immédiatement après le déploiement,
avant tout accès réseau au port d'administration (81) — lui-même restreint via une règle
DOCKER-USER(vue en M2), pour n'être joignable que depuis la
machine elle-même. Les certificats servis par NPM ici sont générés parmkcert, puis
importés manuellement — NPM n'a pas d'intégration native avec mkcert, seulement un import
de certificat personnalisé.
Le client ne connaît que le nom de domaine ; NPM route en interne vers le conteneur par son nom,
sur le réseau partagé — jamais en repassant par l'adresse externe de la machine.
docker compose up -d
# Démarre le stack NPM
docker compose logs -f npm
# Suit les logs -- utile pour confirmer le démarrage avant de créer
# le premier compte administrateur
curl -X POST http://127.0.0.1:81/api/users \
-H "Content-Type: application/json" \
-d '{"name":"Admin","nickname":"admin","email":"admin@example.invalid","password":"...","roles":["admin"]}'
# Création du premier compte via l'API -- à faire IMMÉDIATEMENT après
# le premier démarrage, tant que l'interface graphique n'est pas
# encore accessible pour le faire au clavier
Depuis un navigateur sur le réseau local, ouvre un nom de domaine .internal configuré comme
Proxy Host. La page du service cible doit s'afficher, avec un certificat reconnu (si généré par
mkcert et l'autorité locale installée, vue en M2).
| Symptôme | Cause probable | Solution |
|---|---|---|
Erreur 504 Gateway Timeout sur un Proxy Host |
Hairpin NAT : destination configurée vers l'IP externe de la machine plutôt que le nom du conteneur | Pointer vers le nom du conteneur sur npm_proxy, ou 127.0.0.1 si le service est publié en local uniquement |
| Interface d'administration NPM accessible depuis tout le réseau | Port 81 publié sans restriction |
Restreindre via une règle DOCKER-USER ou une publication en 127.0.0.1 uniquement |
| Fenêtre de vulnérabilité au premier démarrage | Aucun compte administrateur créé immédiatement après le déploiement | Créer le premier compte dès que le conteneur répond, avant d'exposer le port d'administration |
Parce que l'API de création d'utilisateur n'est pas authentifiée tant qu'aucun compte
n'existe — n'importe qui atteignant cette API dans cette fenêtre pourrait créer le premier
compte administrateur à sa place.
Le nom du conteneur cible sur le réseau partagé (ou 127.0.0.1 si le service est publié en
local), jamais l'adresse IP externe de la machine elle-même.
Parce que l'interface d'administration n'a pas besoin d'être accessible depuis tout le réseau —
seuls les services proxifiés doivent l'être, l'administration reste réservée à la machine ou à
un accès restreint.
Sur une machine avec Docker, déploie un stack NPM minimal, crée immédiatement le premier compte
administrateur, puis configure un Proxy Host pointant vers un service fictif — en pointant
volontairement vers l'IP externe de la machine pour observer l'erreur 504 du hairpin NAT, puis
corrige-la en pointant vers le nom du conteneur.
Cette formation est proposée par Deladev, studio web de Loïc D. — création de sites et d'applications, accompagnement et formation sur mesure.
Les projets réalisés · Prestations et tarifs · Le blog tech · Me contacter
Écrite par Loïc D. avec l'assistance de Claude (Anthropic) — un travail à deux.
© 2026 Deladev — publiée sous licence CC BY-NC-ND 4.0. Vous pouvez la lire, y renvoyer par un lien, la partager et la citer en créditant la source. La revendre, l'utiliser dans une prestation ou une formation payante, la republier même partiellement ailleurs, en diffuser une version modifiée ou l'exploiter pour entraîner un modèle d'IA nécessitent une autorisation écrite — pour un usage interne en entreprise, c'est souvent oui, il suffit de demander.