Mettre n8n derrière un reverse proxy Nginx en HTTPS : le guide complet
Publié le 2 août 2026 · 7 min de lecture
Vous avez installé n8n en Docker sur un VPS : l'instance tourne, mais elle répond en HTTP sur le port 5678. Pour l'exposer proprement en https://n8n.votredomaine.fr, il faut un reverse proxy — et si votre serveur héberge déjà d'autres sites, ce reverse proxy s'appelle probablement Nginx. Ce guide donne la configuration complète et fonctionnelle : bloc server avec le support WebSocket indispensable à l'éditeur, certificat Let's Encrypt via certbot, variables d'environnement n8n à ajuster et vérification des webhooks. Nous avons déjà couvert Traefik et Caddy pour mettre n8n en HTTPS ; cet article se concentre sur Nginx, l'option la plus répandue sur les serveurs existants.
Pourquoi un reverse proxy devant n8n
Exposer directement le port 5678 sur Internet pose trois problèmes. D'abord la sécurité : sans TLS, vos identifiants de connexion et les données de vos workflows circulent en clair. Ensuite les intégrations OAuth : Google, Slack ou Notion refusent les URLs de callback en http://, donc une partie de vos credentials ne pourra jamais se configurer. Enfin la mutualisation : un VPS sert rarement une seule application, et Nginx permet de router n8n.votredomaine.fr vers n8n, www.votredomaine.fr vers votre site, le tout derrière les mêmes ports 80 et 443.
Le reverse proxy termine le HTTPS côté public et relaie les requêtes vers n8n en HTTP local ; un seul outil (certbot) renouvelle alors les certificats de toutes vos applications.
Prérequis
Avant de toucher à Nginx, vérifiez ces trois points :
- Un VPS avec Nginx installé et les ports 80/443 ouverts — si vous partez de zéro, notre guide pour choisir un VPS adapté à n8n détaille les critères.
- Un sous-domaine pointant vers l'IP publique du serveur via un enregistrement DNS A (par exemple
n8n.votredomaine.fr). - n8n qui tourne en Docker sur le port 5678, en local uniquement. Si ce n'est pas encore fait, suivez le guide d'installation de n8n avec Docker, avec un détail important dans le
docker-compose.yml:
ports:
- "127.0.0.1:5678:5678"
En liant le port à 127.0.0.1, n8n n'est joignable que depuis le serveur lui-même : Nginx devient l'unique point d'entrée, impossible de contourner le HTTPS via http://votre-ip:5678.
Le certificat Let's Encrypt avec certbot
Créez d'abord un bloc minimal pour que certbot puisse valider le domaine. Dans /etc/nginx/sites-available/n8n.conf :
server {
listen 80;
server_name n8n.votredomaine.fr;
location / {
proxy_pass http://127.0.0.1:5678;
}
}
Activez-le puis demandez le certificat :
sudo ln -s /etc/nginx/sites-available/n8n.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d n8n.votredomaine.fr
Le plugin --nginx obtient le certificat, ajoute les directives ssl_certificate au fichier et met en place la redirection HTTP vers HTTPS. Le renouvellement est automatique via un timer systemd ; validez-le avec sudo certbot renew --dry-run.
Cette automatisation n'est pas un luxe. Une étude de Krombholz, Mayer, Schmiedecker et Weippl présentée à USENIX Security en 2017, « I Have No Idea What I'm Doing » – On the Usability of Deploying HTTPS, a demandé à des participants expérimentés de configurer manuellement TLS sur un serveur web : la majorité a produit des configurations vulnérables ou incomplètes, alors même qu'ils se pensaient compétents. Et une étude d'Aertsen, Korczyński, Moura et leurs co-auteurs publiée en 2017 à l'Applied Networking Research Workshop, No domain left behind: is Let's Encrypt democratizing encryption?, montre que Let's Encrypt a précisément réussi à couvrir le segment des hébergements à petit budget — le profil type d'un VPS n8n. Autrement dit : laissez certbot gérer le TLS, et concentrez votre attention sur le bloc proxy ci-dessous, là où les erreurs se produisent réellement.
La configuration Nginx complète (avec WebSocket)
Une fois le certificat en place, remplacez le contenu du bloc HTTPS généré par certbot par cette version complète :
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl http2;
server_name n8n.votredomaine.fr;
ssl_certificate /etc/letsencrypt/live/n8n.votredomaine.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.votredomaine.fr/privkey.pem;
# Uploads volumineux (import de workflows, fichiers binaires)
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:5678;
# WebSocket : indispensable pour l'éditeur n8n
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# En-têtes transmis à n8n
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Workflows longs : ne pas couper la connexion
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_buffering off;
}
}
server {
listen 80;
server_name n8n.votredomaine.fr;
return 301 https://$host$request_uri;
}
Le bloc map en haut du fichier (hors du server, au niveau http) et les trois directives WebSocket sont la partie que tout le monde oublie — et la cause numéro un du symptôme « Connection lost ». n8n utilise une connexion WebSocket persistante pour l'éditeur et l'affichage des exécutions en temps réel ; sans Upgrade/Connection, Nginx dégrade la connexion en simple requête HTTP et l'éditeur se déconnecte.
Les autres directives en une ligne chacune :
X-Forwarded-Proto $schemeindique à n8n que la requête d'origine était en HTTPS, ce qui évite les URLs générées enhttp://et les problèmes de cookies sécurisés.X-Forwarded-Fortransmet l'IP réelle du client — utile pour les logs et pour sécuriser vos webhooks par filtrage d'IP.proxy_read_timeout 300sévite que Nginx coupe la connexion au bout de 60 secondes (sa valeur par défaut) sur un workflow long déclenché par webhook. Ajustez selon vos cas d'usage.client_max_body_size 50mrelève la limite d'upload (1 Mo par défaut dans Nginx), nécessaire dès que vos workflows reçoivent des fichiers.
Testez et rechargez : sudo nginx -t && sudo systemctl reload nginx.
Les variables d'environnement n8n à ajuster
Nginx ne fait que la moitié du travail : n8n doit savoir sous quelle URL publique il est servi, sinon il continue de générer des liens en http://localhost:5678. Dans le docker-compose.yml :
environment:
- N8N_HOST=n8n.votredomaine.fr
- N8N_PROTOCOL=https
- N8N_PORT=5678
- WEBHOOK_URL=https://n8n.votredomaine.fr/
- N8N_EDITOR_BASE_URL=https://n8n.votredomaine.fr/
- N8N_PROXY_HOPS=1
N8N_HOSTetN8N_PROTOCOLdéfinissent l'identité publique de l'instance.WEBHOOK_URLest la variable la plus importante : c'est elle qui détermine l'URL affichée dans les nodes Webhook et enregistrée auprès des services tiers. Sans elle, vos webhooks pointent vers une adresse injoignable.N8N_EDITOR_BASE_URLsert aux liens générés vers l'éditeur (e-mails d'invitation, callbacks OAuth).N8N_PROXY_HOPS=1indique à n8n qu'il se trouve derrière un proxy de confiance, pour interpréter correctement les en-têtesX-Forwarded-*.
Le détail de chacune (et des autres) se trouve dans notre guide des variables d'environnement n8n. Redémarrez ensuite le conteneur : docker compose up -d.
Tester les webhooks derrière le proxy
Créez un workflow minimal avec un node Webhook, activez-le, et vérifiez trois choses :
- L'URL affichée dans le node commence bien par
https://n8n.votredomaine.fr/webhook/...— sinon,WEBHOOK_URLest mal définie. - Un appel externe aboutit :
curl -i https://n8n.votredomaine.fr/webhook/votre-chemindoit déclencher une exécution visible dans n8n. - Un webhook de test (« Listen for test event ») reçoit bien l'appel : ce mode passe par le WebSocket, c'est donc aussi un test de vos directives
Upgrade/Connection.
Si le webhook de production répond mais pas le mode test, le problème est presque toujours côté WebSocket. Pour aller plus loin sur le fonctionnement des webhooks (chemins test vs production, méthodes, réponses), voyez le guide complet du node Webhook.
Nginx, Traefik ou Caddy : quand choisir quoi
Les trois font le même travail ; le bon choix dépend de votre contexte :
- Nginx s'impose quand il est déjà installé sur le serveur et sert d'autres sites : ajouter un bloc
serverpour n8n prend cinq minutes et ne perturbe rien. Choix naturel aussi si vous maîtrisez déjà sa syntaxe. - Caddy est plus simple pour un serveur mono-service : HTTPS automatique sans certbot, configuration de cinq lignes.
- Traefik brille sur un serveur full-Docker avec découverte automatique des conteneurs par labels.
La comparaison détaillée avec les configurations correspondantes est dans notre guide n8n en HTTPS avec Traefik ou Caddy. Le point commun non négociable : quel que soit le proxy, les variables WEBHOOK_URL et N8N_PROTOCOL doivent être définies.
Bonnes pratiques une fois en production
- Surveillez l'instance et le certificat : un endpoint de healthcheck derrière le proxy et une alerte d'expiration TLS font partie du minimum — notre guide pour superviser une instance n8n montre comment faire, y compris avec n8n lui-même.
- Mettez à jour proprement : le proxy ne change rien à la procédure, mais un
docker compose pullmal préparé peut casser l'instance — suivez la méthode pour mettre à jour n8n sans rien casser. - Sauvegardez la base et la clé de chiffrement : la configuration Nginx se refait en dix minutes, vos workflows non — voyez la stratégie de sauvegarde et restauration PostgreSQL.
- Gardez le port 5678 privé :
127.0.0.1dans le mapping Docker, et un pare-feu (ufw) qui n'ouvre que 22, 80 et 443.
En résumé
Mettre n8n derrière Nginx tient en quatre étapes : lier le port 5678 à l'interface locale, obtenir le certificat avec certbot --nginx, déployer le bloc server complet — trois directives WebSocket, proxy_read_timeout relevé, client_max_body_size — puis déclarer l'URL publique côté n8n via N8N_PROTOCOL, WEBHOOK_URL et N8N_EDITOR_BASE_URL. Le test final : un webhook en mode test qui reçoit son appel. S'il fonctionne, l'éditeur, les exécutions temps réel et vos intégrations OAuth fonctionneront aussi. Et si votre serveur ne fait tourner que n8n, regardez Caddy ou Traefik avant de choisir : le meilleur proxy est celui qui s'intègre à ce que vous avez déjà.
FAQ
Questions fréquentes
Pourquoi l'éditeur n8n affiche-t-il « Connection lost » derrière Nginx ?
Dans la quasi-totalité des cas, il manque les en-têtes WebSocket dans le bloc location : proxy_http_version 1.1, proxy_set_header Upgrade et proxy_set_header Connection. L'éditeur n8n et l'affichage des exécutions en temps réel reposent sur une connexion WebSocket persistante ; sans ces trois directives, Nginx la coupe et l'interface se déconnecte en boucle.
Puis-je servir n8n dans un sous-répertoire comme monsite.fr/n8n plutôt que sur un sous-domaine ?
Techniquement oui via la variable N8N_PATH, mais c'est une source récurrente de problèmes : réécritures d'URL, webhooks et ressources statiques à ajuster. Un sous-domaine dédié (n8n.votredomaine.fr) reste la configuration recommandée et la plus simple à maintenir — un enregistrement DNS A suffit.
Le renouvellement du certificat Let's Encrypt est-il automatique avec certbot ?
Oui. Sur les distributions récentes, l'installation de certbot met en place un timer systemd (ou une tâche cron) qui exécute certbot renew deux fois par jour et recharge Nginx si un certificat a été renouvelé. Vérifiez que tout fonctionne avec certbot renew --dry-run ; le point de vigilance habituel est un pare-feu qui bloquerait le port 80 après coup.
Faut-il bloquer l'accès direct au port 5678 une fois Nginx en place ?
Oui, sinon n'importe qui peut contourner le proxy et joindre n8n en HTTP non chiffré. Le plus propre est de publier le port uniquement sur l'interface locale dans Docker (127.0.0.1:5678:5678) : le port n'est alors joignable que depuis le serveur lui-même, et Nginx devient l'unique porte d'entrée.
Bundle FlowKit Complet
269 €