Guide de déploiement

Installer n8n sur VPS avec Docker : guide complet 2026

Déployer sur un VPS Cloud →

Automatisation12 min de lecture

Installer n8n sur VPS avec Docker : guide complet 2026

n8n est un orchestrateur d'automatisations open source : il connecte vos APIs, déclenche des workflows sur événement et, auto-hébergé, il tourne sans limite d'exécutions ni abonnement cloud. Ce guide couvre l'installation complète sur VPS avec Docker, la configuration du reverse proxy, les variables d'environnement critiques, deux erreurs de production critiques — crash V8 sur plus de 30 workflows simultanés et 502 Bad Gateway nginx — la migration depuis le mode npm, et la sécurisation des données d'exécution persistées mise en lumière par l'advisory GHSA-vrv8-j27g-g7cr d'août 2026.

Pourquoi héberger n8n sur votre VPS

La version cloud de n8n facture à l'exécution au-delà du plan et limite le nombre de workflows actifs. Sur votre VPS, le seul coût est celui du serveur, indépendamment du nombre d'automatisations ou d'appels API. Vous gardez aussi le contrôle total sur les credentials, les charges utiles de webhooks et l'historique des exécutions — aucune donnée ne transite par une infrastructure tierce.

Les bénéfices concrets d'un n8n auto-hébergé

  • Exécutions sans limite : aucun plafond mensuel, aucun surcoût à l'échelle.
  • Credentials et payloads de webhooks confinés sur votre serveur, sans transit externe.
  • Accès aux nodes communautaires et à l'exécution de code personnalisé sans restriction.
  • Webhooks sur votre propre domaine, configurables pour chaque intégration entrante.
  • Coût prévisible : un prix VPS fixe, indépendant du volume d'automatisations.
  • Persistance maîtrisée des workflows et de l'historique dans des volumes que vous sauvegardez.
  • Compatibilité avec Ollama, Flowise ou tout autre service Docker sur le même réseau interne.

Prérequis chiffrés

Avant de commencer, vérifiez que votre VPS répond aux exigences suivantes. Pour un usage modéré, 1 vCPU et 1 Go de RAM suffisent ; prévoyez 2 vCPU et 2 Go dès que vous exécutez des workflows lourds ou concurrents, et 4 Go si vous branchez une base PostgreSQL dédiée ou intégrez un modèle IA local. Comptez 10 Go de disque minimum pour Docker, les volumes et les logs. Côté réseau, le port 5678 ne doit pas être exposé directement — n8n n'écoute que sur 127.0.0.1:5678 et toutes les requêtes passent par le reverse proxy sur le port 443. Un sous-domaine (par exemple n8n.votre-domaine.com) pointant vers l'IP du VPS est requis pour HTTPS et les webhooks entrants. Docker Engine 24+ et Docker Compose v2 (plugin, pas le binaire docker-compose standalone) sont nécessaires.

Installation pas à pas

01

Mettre à jour le VPS et installer Docker

Connectez-vous en SSH et mettez à jour les paquets : apt update && apt upgrade -y. Installez ensuite Docker via le script officiel : curl -fsSL https://get.docker.com | sh. Vérifiez l'installation : docker --version && docker compose version. Créez le répertoire de travail : mkdir -p /opt/n8n && cd /opt/n8n.

02

Créer le fichier docker-compose.yaml

Créez docker-compose.yaml avec le service n8n, un volume nommé pour la persistance et les variables d'environnement essentielles. Déclarez image: n8nio/n8n:latest, restart: unless-stopped, et montez n8n_data:/home/node/.n8n. Exposez uniquement sur 127.0.0.1:5678:5678 pour éviter toute exposition publique directe du port.

03

Fixer les variables d'environnement critiques

Dans la section environment du service, déclarez au minimum : N8N_HOST=n8n.votre-domaine.com, N8N_WEBHOOK_URL=https://n8n.votre-domaine.com/, N8N_PROXY_HOPS=1 (pour que n8n accepte les en-têtes X-Forwarded-* du reverse proxy), N8N_BASIC_AUTH_ACTIVE=true, N8N_BASIC_AUTH_USER=<votre-login> et N8N_BASIC_AUTH_PASSWORD=<mot-de-passe-fort>. Pour la production, stockez ces valeurs dans un fichier .env adjacent et référencez-le via env_file: .env.

04

Démarrer le conteneur

Lancez : docker compose up -d. Vérifiez que le conteneur tourne : docker compose ps. Consultez les logs : docker compose logs -f n8n. n8n est prêt quand la ligne Editor is now accessible via: http://localhost:5678/ apparaît dans les logs. L'interface n'est accessible qu'en 127.0.0.1 à ce stade — c'est intentionnel.

05

Configurer le reverse proxy avec Caddy (recommandé)

Caddy est le reverse proxy le plus simple pour n8n : il gère le certificat Let's Encrypt et le renouvellement sans configuration supplémentaire. Installez Caddy (apt install caddy) puis éditez /etc/caddy/Caddyfile pour ajouter : n8n.votre-domaine.com { reverse_proxy localhost:5678 }. Rechargez : systemctl reload caddy. Avec nginx, ajoutez dans votre bloc location : proxy_set_header X-Forwarded-Host $host;, proxy_set_header X-Forwarded-Proto $scheme; et proxy_set_header X-Real-IP $remote_addr; — sans ces en-têtes, n8n reconstruit des URL de webhooks incorrectes.

06

Vérifier les webhooks entrants

Dans l'éditeur n8n, créez un workflow de test avec un node Webhook. L'URL affichée en mode production doit être exactement https://n8n.votre-domaine.com/webhook/<votre-chemin>. Déclenchez l'appel depuis votre machine locale : curl -X POST https://n8n.votre-domaine.com/webhook/test -d '{}'. Si l'URL affichée contient localhost ou le port 5678, la variable N8N_WEBHOOK_URL n'est pas prise en compte — vérifiez que le conteneur a redémarré après l'ajout de la variable.

07

Brancher PostgreSQL pour la production

SQLite convient pour tester ; en production, préférez PostgreSQL. Ajoutez un service postgres:15 au même docker-compose.yaml, avec un volume dédié pg_data. Dans le service n8n, ajoutez : DB_TYPE=postgresdb, DB_POSTGRESDB_HOST=postgres, DB_POSTGRESDB_DATABASE=n8n, DB_POSTGRESDB_USER=n8n, DB_POSTGRESDB_PASSWORD=<mot-de-passe>. Redémarrez l'ensemble : docker compose up -d. La base SQLite n'est pas migrée automatiquement — exportez vos workflows avant de basculer.

Durcissement et mode queue

Trois réflexes de production : (1) Ne jamais exposer le port 5678 sur l'interface publique — gardez la liaison 127.0.0.1:5678. (2) Activez l'authentification : en v1.x, N8N_BASIC_AUTH_ACTIVE=true ; en v1.27+, préférez l'authentification native via l'interface (Paramètres → Sécurité). (3) Pour des workflows IA ou à longue durée, passez en mode queue avec une instance worker séparée et une file Redis : cela isole les exécutions longues de l'interface et permet de scaler horizontalement sans reconfigurer les webhooks.

Sécuriser les exécutions persistées (advisory GHSA-vrv8-j27g-g7cr)

En août 2026, l'advisory GHSA-vrv8-j27g-g7cr a révélé que trois nodes versent les credentials déchiffrés dans les données d'exécution persistées en cas d'erreur : le node Strapi (tokens OAuth écrits en clair dans execution_data), le node SeaTable (clés API inscrites dans les logs d'exécution d'erreur) et le node Mailcheck (identifiants SMTP persistés dans execution_data). Ces secrets restent lisibles par tout utilisateur ayant accès aux logs d'exécution dans l'interface n8n. Sur une instance sans pruning, ils s'accumulent indéfiniment.

Quatre gestes pour corriger et prévenir

01

Mettre à jour vers la version corrigeant l'advisory

La mise à jour est le seul correctif complet pour les trois nodes. Vérifiez votre version courante : docker exec n8n n8n --version. Pulls la dernière image et relancez : docker compose pull && docker compose up -d. Pour la branche stable, la correction est disponible à partir de la version 2.35.4 ; pour la branche v1, à partir de la version 1.123.73. Confirmez l'absence de credentials exposés dans les logs d'erreur après mise à jour.

02

Activer le pruning des exécutions

Ajoutez deux variables dans la section environment du service n8n : EXECUTIONS_DATA_PRUNE=true et EXECUTIONS_DATA_MAX_AGE=168 (7 jours, exprimé en heures). Redémarrez le conteneur : docker compose restart n8n. Le pruning supprime les données d'exécution au-delà de l'âge défini. Il réduit la surface d'exposition mais ne remplace pas la mise à jour — des données exposées avant le pruning ont déjà pu être lues.

03

Restreindre l'accès aux logs d'exécution

En mode multi-utilisateurs, vérifiez dans Paramètres → Utilisateurs que seuls les administrateurs peuvent consulter les logs d'exécution. Ce garde-fou limite la propagation si des données sensibles ont été persistées avant la mise à jour. Sur une instance mono-utilisateur exposée sur un serveur partagé, vérifiez que le port 5678 n'est pas accessible directement depuis l'extérieur.

04

Mesure conservatoire avant mise à jour

Sur une instance non encore mise à jour : désactivez ou retirez les workflows utilisant les nodes Strapi, SeaTable ou Mailcheck. Le problème ne se déclenche qu'en cas d'erreur d'exécution sur ces nodes, mais l'erreur peut survenir sur une coupure réseau ou un token expiré — des conditions hors de votre contrôle direct.

Fatal V8 crash avec plus de 30 workflows actifs

Symptôme. L'instance n8n s'arrête brutalement avec l'erreur FATAL ERROR: invalid-mark-compact are transition dans les logs Docker. Le conteneur redémarre si restart: unless-stopped est configuré, mais le crash se reproduit dès que la charge repasse le même seuil. Aucun message d'erreur dans l'interface : le conteneur disparaît sans prévenir.

Cause. Cette erreur est une panique du moteur V8 (le moteur JavaScript embarqué dans Node.js) lors d'un cycle de garbage collection. Elle se déclenche quand le tas mémoire de V8 est saturé — typiquement à partir de 30 workflows s'exécutant simultanément sur un VPS avec moins de 2 Go de RAM alloués au processus. Chaque workflow actif maintient un contexte d'exécution en mémoire ; au-delà d'un certain seuil, le GC tente une transition mark-compact sur un tas déjà corrompu, ce qui provoque le crash fatal. Le problème n'a pas de recovery automatique : n8n ne dispose pas d'un mécanisme de dégradation gracieuse à ce niveau.

Fix immédiat. Augmentez la limite de tas V8 en ajoutant la variable d'environnement suivante dans le service n8n de votre docker-compose.yaml : NODE_OPTIONS=--max-old-space-size=2048. Cela alloue 2 Go au tas V8. Redémarrez le conteneur : docker compose restart n8n. Observez les logs pendant quelques minutes pour confirmer l'absence de crash.

Fix structurel. La limite mémoire du conteneur doit correspondre à la limite V8. Si votre docker-compose.yaml déclare mem_limit: 1g et que vous passez --max-old-space-size=2048, le OOM killer tue le conteneur avant que V8 ne puisse l'utiliser. Règle : allouez au moins 2 Go de RAM à la VM au-delà de 30 workflows actifs, et passez NODE_OPTIONS=--max-old-space-size=1536 (laissez 512 Mo pour le reste du système). Pour une installation avec plus de 50 workflows, préférez le mode queue (instance worker Redis séparée) qui découple les exécutions du processus principal et répartit la charge mémoire. Source : community.n8n.io thread #308425.

502 Bad Gateway persistant derrière nginx

Symptôme. Les requêtes courtes réussissent mais certains workflows retournent 502 Bad Gateway depuis nginx — notamment les workflows qui appellent des APIs externes lentes, traitent de gros volumes de données ou enchaînent de nombreux nodes. Le 502 se produit exactement 60 secondes après le début de l'exécution, même si n8n continue de travailler en arrière-plan.

Cause. nginx attend par défaut 60 secondes une réponse du backend avant de fermer la connexion (proxy_read_timeout = 60 s). Pour n8n, le backend est le processus qui exécute le workflow : si l'exécution prend plus de 60 secondes, nginx coupe la connexion et retourne un 502. n8n continue l'exécution en arrière-plan (le workflow se termine côté serveur), mais le client ne reçoit jamais la réponse — ce qui fait croire à un échec alors que le résultat a bien été produit. Le comportement est aggravé avec les webhooks synchrones qui attendent la fin du workflow pour répondre (Respond to Webhook node en fin de flux).

Fix. Ajoutez ces deux directives dans le bloc location de votre configuration nginx qui proxie vers n8n :

proxy_read_timeout 300;
proxy_send_timeout 300;

La valeur de 300 secondes (5 minutes) couvre la grande majorité des workflows longs. Pour des workflows exceptionnellement longs (import de données massif, chaînes IA multi-étapes), montez à 600 s. Rechargez nginx : nginx -t && systemctl reload nginx. Notez que cette valeur ne remplace pas le timeout de connexion (proxy_connect_timeout, gardez-le à 60 s — il ne s'applique qu'à l'établissement initial de la connexion TCP).

Vérification. Lancez un workflow volontairement lent (node Wait réglé sur 90 s, par exemple) et vérifiez que la réponse arrive au-delà de 60 secondes sans erreur. Si le 502 persiste après la modification, vérifiez que vous avez édité le bon bloc location — une configuration nginx fragmentée en plusieurs fichiers include peut avoir un bloc plus spécifique qui override le timeout. Source : community.n8n.io thread #274581.

Breaking changes à connaître (v1.27–v1.31)

Trois changements des versions récentes peuvent casser silencieusement une instance existante.

Renommage du paramètre OAuth 2.0 dans HTTP Request. Le champ oauthTokenData a été renommé dans les versions 1.27-1.31. Les requêtes authentifiées via OAuth 2.0 dans le node HTTP Request peuvent cesser de fonctionner sans message d'erreur explicite — n8n envoie une requête non authentifiée plutôt que de lever une exception. Vérifiez chaque workflow qui utilise ce node avec des credentials OAuth après une mise à jour.

Format de l'URL de webhook. Le format de l'URL générée par les nodes Webhook a changé dans cette plage de versions. Si vous avez copié des URL de webhook en dur dans des services tiers (Stripe, GitHub, Slack…), re-vérifiez-les après la mise à jour.

Dépréciation de $item(). La fonction $item() disponible dans les expressions et le node Function est marquée dépréciée. Son remplacement est $input.item pour l'item courant ou $('Nom du node').item pour les items d'un node précédent. Elle fonctionne encore en v1.x.

La liste complète des breaking changes est disponible sur la documentation officielle n8n.

Dépannage des erreurs courantes

Le port 5678 est inaccessible. Vérifiez que le conteneur tourne (docker compose ps) et que vous écoutez bien sur 127.0.0.1:5678. Si vous testez depuis la machine locale, curl http://127.0.0.1:5678/ doit répondre.

Les webhooks affichent localhost au lieu du domaine. La variable N8N_WEBHOOK_URL est absente ou mal définie. Ajoutez N8N_WEBHOOK_URL=https://n8n.votre-domaine.com/ (avec le slash final) et redémarrez : docker compose restart n8n.

N8N_PROXY_HOPS manquant : erreur 502 ou boucle. Sans cette variable, n8n rejette ou boucle sur les en-têtes X-Forwarded-*. Ajoutez N8N_PROXY_HOPS=1 dans l'environnement du conteneur.

Erreur de permissions sur le volume. Le conteneur n8n tourne sous l'UID 1000. Si le dossier de données a été créé par root, les permissions sont incorrectes : chown -R 1000:1000 /opt/n8n/data puis docker compose restart n8n.

La base PostgreSQL refuse la connexion. Vérifiez que le service postgres est sur le même réseau Docker que n8n (docker network inspect <nom>) et que les variables DB_POSTGRESDB_HOST, DB_POSTGRESDB_USER et DB_POSTGRESDB_PASSWORD correspondent exactement à celles définies dans le service postgres.

Crash V8 brutal (FATAL ERROR: invalid-mark-compact). Le tas mémoire de V8 est saturé : plus de 30 workflows simultanés avec une RAM insuffisante. Ajoutez NODE_OPTIONS=--max-old-space-size=2048 dans l'environnement du service n8n et augmentez la RAM du VPS à 2 Go minimum. Voir la section dédiée ci-dessus.

502 Bad Gateway persistant (exactement 60 s). Le proxy_read_timeout nginx est au défaut (60 s). Portez-le à 300 s dans le bloc location nginx pointant vers n8n. Voir la section dédiée ci-dessus.

Credentials visibles dans les logs d'exécution. Vous utilisez un des nodes Strapi, SeaTable ou Mailcheck sur une version antérieure au correctif de l'advisory GHSA-vrv8-j27g-g7cr. Mettez à jour vers la version corrigeant l'advisory et activez le pruning des exécutions. Voir la section dédiée ci-dessus.

Maintenir et faire évoluer l'instance

Pour les mises à jour, deux approches : Watchtower (surveillance automatique de l'image et redémarrage) ou une tâche cron manuelle (docker pull n8nio/n8n:latest && docker compose up -d). Dans les deux cas, lisez les notes de version avant une mise à jour majeure — les breaking changes listés ci-dessus sont représentatifs du rythme des changements. Gardez vos exports de workflows à jour dans un dépôt git : c'est la sauvegarde la plus rapide à restaurer en cas d'incident.

Pour les advisories de sécurité, suivez la page GitHub Security Advisories du dépôt n8n — les versions stables publient les correctifs critiques rapidement, et chaque advisory liste les versions affectées et la version minimale corrigeant le problème.

Votre VPS pour n8n, en quelques minutes

ServOrbit propose des VPS Linux avec accès root, IPv4 dédiée et SSD NVMe — prêts à accueillir Docker et n8n sans configuration supplémentaire. Consultez la page développeurs pour choisir la configuration adaptée à vos workflows.

Besoin d'aide ?

Parcourez notre centre d'aide et notre FAQ, ou contactez notre équipe — rappel, WhatsApp ou e-mail. Support en français, anglais et arabe.