Reverse proxy avec Nginx Proxy Manager
Plusieurs apps sur un VPS, un seul port 443 et du HTTPS à gérer pour chacune : Nginx Proxy Manager règle tout ça avec une interface web. Voici comment l'installer et publier vos services proprement.
Plusieurs applications peuvent cohabiter sur un même VPS : n8n, Portainer, une API métier ou encore un site web. Le problème apparaît au moment de les rendre accessibles : une seule application peut écouter directement sur les ports HTTP 80 et HTTPS 443, et chaque service doit disposer d’un certificat TLS valide.
Nginx Proxy Manager, souvent abrégé NPM, résout ce problème en devenant le point d’entrée unique du serveur. Il reçoit les requêtes, reconnaît le domaine demandé, puis les transmet vers la bonne application interne. Son interface web permet de créer ces règles sans écrire manuellement une configuration Nginx. Elle automatise également l’obtention et le renouvellement des certificats Let’s Encrypt.
Dans ce guide, nous allons exposer n8n.exemple.fr vers un conteneur n8n écoutant sur le port interne 5678. La même méthode pourra ensuite être appliquée à Portainer, une API ou un site.
Prérequis
Il vous faut :
- un serveur Linux avec une adresse IPv4 publique
- Docker Engine et le plugin Docker Compose (voir installer Docker sur un VPS)
- un nom de domaine dont vous contrôlez la zone DNS
- les ports TCP 80 et 443 accessibles depuis Internet
- un accès SSH au serveur
Créez un enregistrement DNS de type A pour chaque sous-domaine à publier. Par exemple :
n8n.exemple.fr A 203.0.113.10
portainer.exemple.fr A 203.0.113.10
api.exemple.fr A 203.0.113.10
Remplacez l’adresse d’exemple par l’adresse publique du VPS. La propagation DNS doit être terminée avant de demander un certificat Let’s Encrypt.
Les VPS TalCloud répondent à ce type d’usage avec un hébergement en France, du stockage NVMe, une protection Anti-DDoS Netrix et un support humain, à partir de 4,99 € par mois.
Installer Nginx Proxy Manager avec Docker Compose
NPM a besoin de volumes persistants pour conserver sa configuration et ses certificats. Nous allons également utiliser une base MariaDB séparée. Le réseau proxy permettra ensuite aux applications Docker de communiquer avec NPM sans publier leurs ports sur Internet.
Créez un répertoire de travail et placez-y un fichier compose.yml :
services:
npm:
image: jc21/nginx-proxy-manager:latest
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- "80:80"
- "127.0.0.1:81:81"
- "443:443"
environment:
DB_MYSQL_HOST: db
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: npm
DB_MYSQL_PASSWORD: CHANGE_ME_DB_PASSWORD
DB_MYSQL_NAME: npm
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
depends_on:
- db
networks:
- proxy
- database
db:
image: jc21/mariadb-aria:latest
container_name: nginx-proxy-manager-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: CHANGE_ME_ROOT_PASSWORD
MYSQL_DATABASE: npm
MYSQL_USER: npm
MYSQL_PASSWORD: CHANGE_ME_DB_PASSWORD
volumes:
- ./mysql:/var/lib/mysql
networks:
- database
networks:
proxy:
name: proxy
database:
Remplacez les deux mots de passe par des valeurs longues et uniques. La valeur de DB_MYSQL_PASSWORD doit être strictement identique à celle de MYSQL_PASSWORD.
Démarrez ensuite les conteneurs :
docker compose up -d
Vérifiez leur état :
docker compose ps
docker compose logs --tail=100 npm
Les dossiers data, letsencrypt et mysql contiennent les données persistantes. Sauvegardez-les régulièrement. Une suppression suivie d’une recréation des conteneurs ne doit pas effacer ces répertoires.
Le port 81 est ici lié uniquement à 127.0.0.1. L’interface d’administration n’est donc pas directement joignable depuis Internet.
Effectuer la première connexion
Depuis votre poste, ouvrez un tunnel SSH vers le port d’administration :
ssh -L 8181:127.0.0.1:81 utilisateur@adresse-du-vps
Gardez cette session ouverte, puis rendez-vous sur :
http://127.0.0.1:8181
Sur les versions qui utilisent encore les identifiants initiaux classiques, connectez-vous avec :
Email: admin@example.com
Mot de passe: changeme
NPM demande normalement de modifier le profil et le mot de passe lors de la première connexion. Faites-le immédiatement. Utilisez une adresse email valide et un mot de passe différent de ceux de la base de données.
Si votre version affiche directement un assistant de création du premier administrateur, suivez cet assistant plutôt que de chercher les identifiants historiques.
Relier n8n au réseau du proxy
Lorsque n8n fonctionne dans un autre fichier Compose, rattachez-le au réseau Docker proxy :
services:
n8n:
image: docker.n8n.io/n8nio/n8n
restart: unless-stopped
expose:
- "5678"
networks:
- proxy
networks:
proxy:
external: true
expose documente le port accessible entre conteneurs, mais ne le publie pas sur l’adresse publique du VPS. Évitez une règle comme "5678:5678" si seul NPM doit joindre n8n.
Les deux conteneurs étant sur le même réseau, NPM peut utiliser le nom de service n8n comme destination. Pour une application installée directement sur le système, utilisez son adresse privée ou une adresse explicitement accessible depuis le conteneur NPM.
Créer le Proxy Host
Dans l’interface NPM, ouvrez Hosts, puis Proxy Hosts et cliquez sur Add Proxy Host.
Renseignez les champs suivants :
Domain Names: n8n.exemple.fr
Scheme: http
Forward Hostname / IP: n8n
Forward Port: 5678
Activez Block Common Exploits. Activez également Websockets Support pour les applications qui utilisent des connexions WebSocket ou des mises à jour en temps réel.
Enregistrez la règle. Une requête reçue pour n8n.exemple.fr sera désormais transmise au conteneur n8n sur le port 5678. Le port interne reste invisible depuis Internet.
Si NPM affiche une erreur 502 Bad Gateway, vérifiez en priorité le nom du conteneur, le port cible, l’état de l’application et la présence des deux services sur le réseau proxy.
Activer HTTPS avec Let’s Encrypt
Modifiez le Proxy Host, puis ouvrez l’onglet SSL.
Dans SSL Certificate, choisissez Request a new SSL Certificate. Saisissez une adresse email valide pour les notifications Let’s Encrypt, acceptez les conditions, puis activez :
Force SSLHTTP/2 SupportHSTS Enableduniquement après avoir validé le bon fonctionnement HTTPS
Enregistrez. NPM lance automatiquement le challenge Let’s Encrypt et installe le certificat. Le domaine doit déjà pointer vers le VPS, et le port 80 doit être joignable publiquement pour le challenge HTTP.
NPM renouvelle ensuite les certificats avant leur expiration. Le volume ./letsencrypt permet de les conserver lors des mises à jour du conteneur.
Sécuriser Nginx Proxy Manager
L’interface d’administration mérite davantage de protection que les applications publiques. Le binding local du port 81 et le tunnel SSH constituent une solution simple. Si vous devez publier cette interface, placez-la derrière un Proxy Host protégé, utilisez une Access List et limitez si possible les adresses IP autorisées.
Dans le pare-feu du VPS, ouvrez uniquement les services nécessaires :
22/tcp SSH, idéalement limité aux adresses d'administration
80/tcp HTTP et validation Let's Encrypt
443/tcp HTTPS
Ne rendez publics ni le port 81, ni le port 3306 de MariaDB, ni les ports internes des applications.
Les Access Lists de NPM permettent d’ajouter une authentification HTTP ou des règles par adresse IP. Elles conviennent bien à Portainer, à une interface de test ou à un tableau de bord interne. Attention avec n8n : protéger tout le domaine par authentification HTTP peut bloquer les webhooks entrants. Dans ce cas, utilisez l’authentification native de n8n ou séparez les endpoints concernés.
Conservez aussi NPM à jour après sauvegarde :
docker compose pull
docker compose up -d
Gérer plusieurs applications
Ajoutez un Proxy Host par service :
n8n.exemple.fr -> n8n:5678
portainer.exemple.fr -> portainer:9000
api.exemple.fr -> api:3000
www.exemple.fr -> site:8080
Chaque application rejoint le réseau proxy, sans publier son port sur l’hôte. NPM reste le seul service exposé sur 80 et 443, sélectionne la destination grâce au nom de domaine et gère un certificat distinct pour chaque hôte.
Avant d’ajouter une nouvelle application, la séquence concrète reste la même : créer son enregistrement DNS, joindre le conteneur au réseau proxy, créer le Proxy Host, demander le certificat Let’s Encrypt, tester HTTPS, puis fermer tout port applicatif devenu inutile.