Auto-héberger n8n sur un serveur à 6 $
Suivez ça sur votre propre serveur. Commencer gratuitement, sans carte
Tout outil d’automatisation de workflows qui facture à l’exécution transforme « connecter ces deux API » en coût récurrent qui grossit exactement avec la chose que vous avez automatisée pour arrêter d’y penser. n8n fait le même travail que Zapier ou Make, des workflows visuels qui appellent des API sans que vous ayez à écrire et maintenir du code de liaison, mais en logiciel open source que vous faites tourner vous-même. À la fin de ce guide, vous aurez votre propre instance n8n qui tourne sur un serveur à 6 $/mois, accessible en HTTPS sur votre propre domaine, appuyée sur Postgres plutôt qu’un simple fichier SQLite, avec des sauvegardes et un chemin de mise à jour qui ne vous laissera pas en plan.
Ce qu’il vous faut
- Un serveur. Le Basic Droplet de DigitalOcean à 6,00 $/mois donne 1 vCPU, 1 Go de RAM et 25 Go de SSD, ce qui suffit pour faire tourner n8n, Postgres et un reverse proxy ensemble sur une seule machine, pour un usage personnel ou en petite équipe. Un serveur privé virtuel Ubuntu 24.04 chez un autre fournisseur fonctionne de la même façon.
- Un nom de domaine (ou un sous-domaine d’un domaine que vous possédez déjà), avec accès à ses paramètres DNS.
- Docker et le plugin Docker Compose installés sur le serveur (couvert à l’étape 2).
- Un terminal et un accès SSH au serveur.
Étape 1 : créer le serveur et pointer un domaine vers lui
Déployez un droplet Ubuntu 24.04 sur le plan Basic à 6 $/mois de DigitalOcean (1 vCPU, 1 Go de RAM, 25 Go de SSD). Notez son adresse IP publique.
Dans les paramètres DNS de votre domaine, ajoutez un enregistrement A pointant un sous-domaine, par exemple n8n.votredomaine.com, vers cette IP :
Type: A
Name: n8n
Value: <l'IP de votre serveur>
TTL: 300
La propagation DNS peut prendre de quelques minutes à quelques heures. Vous devriez voir dig n8n.votredomaine.com +short retourner l’IP de votre serveur avant de poursuivre, puisque les étapes suivantes en dépendent.
Étape 2 : installer Docker
Connectez-vous en SSH au serveur et installez Docker Engine ainsi que le plugin Compose :
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
Déconnectez-vous et reconnectez-vous pour que le changement de groupe prenne effet, puis vérifiez que les deux composants sont bien présents :
docker --version
docker compose version
Vous devriez voir une version de Docker et une version de Compose s’afficher, sans erreur de type « command not found ».
Étape 3 : préparer le dossier du projet et ses secrets
Créez un dossier pour la pile de services et un fichier .env pour tout ce qui ne devrait pas se retrouver dans le fichier compose lui-même :
mkdir -p ~/n8n && cd ~/n8n
Générez une vraie clé de chiffrement. n8n s’en sert pour chiffrer chaque identifiant stocké dans sa base de données, donc la perdre veut dire perdre l’accès à tous les identifiants sauvegardés, pas seulement ceux de cette installation :
openssl rand -base64 32
Créez .env avec cette clé, votre domaine, un fuseau horaire et un mot de passe de base de données :
# .env
DOMAIN=n8n.votredomaine.com
GENERIC_TIMEZONE=America/Toronto
N8N_ENCRYPTION_KEY=<collez la clé que vous venez de générer>
POSTGRES_USER=n8n
POSTGRES_PASSWORD=<un long mot de passe aléatoire>
POSTGRES_DB=n8n
Réglez ses permissions pour que seul votre utilisateur puisse le lire :
chmod 600 .env
Étape 4 : écrire le fichier Docker Compose
n8n inclut par défaut une base de données SQLite, ce qui convient pour essayer l’outil mais pas pour une instance qui tourne en continu avec plus qu’une poignée de workflows. Postgres est la base de données que n8n recommande lui-même une fois dépassée l’étape du simple test, donc cette configuration l’utilise dès le départ.
Créez docker-compose.yml :
services:
n8n:
image: n8nio/n8n:1.68.0
restart: unless-stopped
environment:
- N8N_HOST=${DOMAIN}
- N8N_PROTOCOL=https
- N8N_PORT=5678
- N8N_WEBHOOK_URL=https://${DOMAIN}/
- N8N_PROXY_HOPS=1
- N8N_RUNNERS_ENABLED=true
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- n8n_data:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
networks:
- n8n-net
postgres:
image: postgres:16.4-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 10
networks:
- n8n-net
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
environment:
- DOMAIN=${DOMAIN}
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
depends_on:
- n8n
networks:
- n8n-net
networks:
n8n-net:
volumes:
n8n_data:
postgres_data:
caddy_data:
caddy_config:
Quelques choix méritent une explication :
- L’image de n8n est fixée à
1.68.0plutôt qu’àlatest. Un outil d’automatisation qui se met à jour silencieusement au redémarrage du serveur, en entraînant vos workflows avec lui dans ce qui a changé, n’est pas un bon compromis. Vous choisissez quand mettre à jour, voir l’étape 7. N8N_PROXY_HOPS=1etN8N_WEBHOOK_URLcomptent parce que n8n se trouve ici derrière Caddy plutôt qu’exposé directement à Internet. Sans ça, n8n ne connaît pas sa propre adresse HTTPS publique et enregistre les mauvaises URL de webhook auprès des services externes.N8N_RUNNERS_ENABLED=trueactive le task runner de n8n, qui exécute les scripts des nœuds Code dans un processus isolé plutôt que dans le processus principal de n8n. Omettre ceci sur une version 1.x veut dire qu’un script dans un nœud Code tourne sans aucune isolation, ce qui compte dès que vous faites rouler des workflows que vous n’avez pas écrits vous-même.- Seul Caddy publie des ports vers l’hôte. n8n et Postgres ne sont accessibles que sur le réseau Docker interne, pas directement depuis Internet.
Étape 5 : écrire le Caddyfile et tout démarrer
Caddy gère automatiquement le certificat TLS de Let’s Encrypt, tant que le DNS pointe déjà vers le serveur et que les ports 80 et 443 sont accessibles depuis Internet. Créez Caddyfile dans le même dossier :
{$DOMAIN} {
reverse_proxy n8n:5678
}
Démarrez la pile de services :
docker compose up -d
Observez son démarrage et vérifiez que Caddy a bien obtenu un certificat :
docker compose logs -f caddy
Vous devriez voir une ligne mentionnant un certificat obtenu pour votre domaine, puis visiter https://n8n.votredomaine.com dans un navigateur devrait afficher l’écran de configuration de n8n avec un cadenas valide, sans avertissement de certificat. Créez votre compte propriétaire à cet endroit; c’est la configuration de premier démarrage de n8n lui-même, pas quelque chose que cette pile configure pour vous.
Étape 6 : sauvegarder les workflows, les identifiants et la clé de chiffrement
Trois choses doivent être sauvegardées : la base de données Postgres (vos workflows, exécutions et identifiants), le volume n8n_data (l’état local propre à n8n, incluant tout ce qui n’est pas dans la base de données), et le fichier .env (votre clé de chiffrement, sans laquelle les identifiants de cette base de données deviennent illisibles).
Un export quotidien de Postgres, gardé ailleurs que sur le serveur :
docker compose exec -T postgres pg_dump -U n8n n8n > "n8n-backup-$(date +%F).sql"
Mettez ça dans une tâche cron et copiez le résultat ailleurs que sur ce droplet, un espace de stockage objet, une autre machine, n’importe où sauf ce serveur. Une sauvegarde qui ne vit que sur le serveur qu’elle sauvegarde ne survit pas au scénario de panne qui détruit justement un serveur.
Pour le volume et le fichier .env :
docker run --rm -v n8n_n8n_data:/data -v $(pwd):/backup alpine \
tar czf /backup/n8n-data-backup.tar.gz -C /data .
cp .env ~/n8n-env-backup-$(date +%F)
Gardez cette sauvegarde de .env à part, dans un endroit avec accès contrôlé; elle contient à la fois votre mot de passe de base de données et votre clé de chiffrement.
Étape 7 : mettre à jour n8n sans mauvaise surprise
Vérifiez la version que vous faites actuellement tourner, lisez les notes de version de n8n pour tout ce qui se trouve entre cette version et celle vers laquelle vous migrez, puis changez le tag dans docker-compose.yml :
image: n8nio/n8n:1.69.0
Récupérez et redémarrez seulement ce service :
docker compose pull n8n
docker compose up -d n8n
Vous devriez voir les journaux de n8n afficher un démarrage propre sans erreur de migration de base de données échouée, et vos workflows existants devraient toujours être là en vous reconnectant. Si une migration échoue, votre sauvegarde Postgres de l’étape 6 est le chemin de retour vers la version précédente.
Le raccourci : le faire avec Railyard
Tout ce qui précède, un n8n appuyé sur Postgres avec une clé de chiffrement générée automatiquement, un volume de données persistant et le HTTPS déjà en place, existe aussi comme gabarit en un clic :
https://app.railyard.run/deploy?template=n8n
Ce gabarit à un seul conteneur convient au même usage que la configuration manuelle ci-dessus : un utilisateur ou une petite équipe qui fait tourner de l’automatisation interne. Si vous dépassez cet usage plus tard, avec assez de volume de workflows pour que la livraison des webhooks et l’exécution se mettent à se disputer le même processus, l’architecture de n8n propose justement un mode « queue » qui sépare ces deux tâches, et c’est offert comme gabarit de pile séparé : choisissez n8n (queue mode) dans le catalogue de gabarits plutôt que de le déployer directement depuis un lien, puisqu’un gabarit de pile exige que vous confirmiez d’abord ses services. Il fait tourner les processus web et worker de n8n contre leur propre Postgres et un Redis protégé par mot de passe pour la file d’attente.
Si vous préférez commencer par Railyard en général avant de trancher pour n8n en particulier, le guide de démarrage couvre les bases, et bases de données et sauvegardes explique comment les sauvegardes fonctionnent à travers tous les gabarits, pas seulement celui-ci. Bouton de déploiement couvre le format du lien ?template= lui-même si vous voulez en intégrer un ailleurs. Pour une comparaison plus large de ce qu’un droplet à 6 $ vous donne face à une alternative gérée, voir coûts d’hébergement.
Dépannage
Caddy n’obtient jamais de certificat, ou le navigateur affiche un avertissement de certificat. C’est presque toujours une question de DNS, pas de Caddy. Lancez dig n8n.votredomaine.com +short depuis votre propre machine et confirmez que ça retourne bien l’IP du serveur, pas une ancienne IP, et pas rien du tout. Let’s Encrypt a aussi besoin que le port 80 soit accessible depuis Internet pour la validation initiale, alors vérifiez que le pare-feu ou le groupe de sécurité de votre fournisseur autorise bien les connexions entrantes sur 80 et 443, pas seulement 443.
docker compose up échoue avec « port is already allocated ». Quelque chose d’autre sur la machine est déjà lié au port 80 ou 443, souvent une installation par défaut de Nginx ou Apache. Trouvez-le avec sudo ss -tlnp | grep -E ':80|:443' et arrêtez ce service, ou changez les ports publiés par Caddy si vous avez vraiment besoin des deux en même temps.
Les journaux de n8n montrent des URL de webhook qui pointent vers la mauvaise adresse, ou vers http plutôt que https. Vérifiez que N8N_HOST, N8N_PROTOCOL et N8N_WEBHOOK_URL dans le fichier compose correspondent bien à votre vrai domaine et à https, et que N8N_PROXY_HOPS=1 est bien défini. Sans ça, n8n ne fait pas confiance aux en-têtes transmis par Caddy et retombe sur une estimation de sa propre adresse.
Le conteneur Postgres redémarre en boucle, ou n8n n’arrive pas à se connecter à la base de données. Vérifiez d’abord docker compose logs postgres pour voir l’erreur réelle. Un POSTGRES_PASSWORD qui ne correspond pas au DB_POSTGRESDB_PASSWORD utilisé par n8n pour se connecter est la cause la plus courante, habituellement après avoir modifié .env alors que le volume Postgres avait déjà été initialisé avec l’ancien mot de passe; Postgres ne lit ces variables d’environnement qu’au tout premier démarrage, avec un dossier de données vide.
Le conteneur démarre puis s’arrête tout de suite, ou le volume affiche des erreurs de permission. Ça arrive habituellement si vous montez un dossier de l’hôte plutôt qu’un volume Docker nommé pour /home/node/.n8n. L’image de n8n tourne avec un utilisateur non root, et un dossier créé par root sur l’hôte ne lui sera pas accessible en écriture. Les volumes nommés, comme dans le fichier compose ci-dessus, évitent complètement ce problème puisque Docker gère lui-même leur propriété.
Le serveur manque de mémoire sous une vraie charge. Un droplet de 1 Go qui fait tourner n8n, Postgres et Caddy ensemble a peu de marge. Ajoutez un fichier swap comme tampon (fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile), et si vous faites rouler des workflows qui traitent de gros volumes de données ou beaucoup d’exécutions en parallèle, passez à un droplet de 2 Go plutôt que de vous fier au swap comme solution permanente.
Foire aux questions
Ai-je besoin de Postgres, ou SQLite suffit-il? SQLite, la base par défaut de n8n, convient pour essayer l’outil, mais ne gère pas bien plus qu’une poignée de workflows simultanés et ce n’est pas ce que n8n recommande dès qu’une instance est réellement utilisée au quotidien. Partir avec Postgres dès le départ, comme dans ce guide, évite une migration plus tard.
Puis-je faire ça sans domaine, juste avec l’IP du serveur? Le HTTPS automatique de Caddy a besoin d’un vrai nom de domaine; Let’s Encrypt n’émet pas de certificats pour des adresses IP brutes. Vous pouvez faire tourner l’outil en HTTP simple sur une IP pour un test rapide en pointant un navigateur directement sur le port 5678, mais ne stockez pas de vrais identifiants dans une instance qui n’est pas derrière HTTPS.
Combien ça coûte réellement, au final? Le serveur coûte 6 $/mois. n8n lui-même est un logiciel open source gratuit, sans limite d’exécution de sa part; vous payez pour la machine sur laquelle il tourne, pas pour ce qui y tourne.
Qu’arrive-t-il à mes workflows si je perds la clé de chiffrement? Chaque identifiant que n8n a stocké devient illisible. La structure des workflows survit, mais tout ce qui avait besoin d’une clé d’API ou d’un jeton OAuth sauvegardé devra voir ces identifiants réentrés. C’est exactement pour ça que l’étape 6 sauvegarde .env séparément de la base de données.
La configuration à un seul conteneur ici est-elle la même que celle du gabarit n8n de Railyard? Presque, avec une vraie différence : le gabarit de Railyard n’inclut pas Postgres par défaut, puisque la plupart des installations à un seul utilisateur n’en ont pas besoin dès le premier jour. L’architecture, un conteneur n8n avec une clé de chiffrement générée et un volume de données persistant, c’est la même idée; ce guide ajoute Postgres parce que c’est le choix par défaut le plus honnête pour tout ce que vous comptez garder en fonction longtemps.
Les deux chemins mènent au même résultat : votre propre serveur d’automatisation, vos propres données, et une facture qui ne bouge pas quand vos workflows travaillent plus.
Pourquoi les gens choisissent Railyard pour ça
- Votre propre compte infonuagique. Déployez sur DigitalOcean, Hetzner, Vultr, AWS, OVHcloud, ou n'importe quel serveur Linux par SSH, facturé directement par votre fournisseur, sans majoration.
- Un prix fixe par équipe. L'offre gratuite est gratuite pour toujours : un serveur plus un serveur de base de données, trois applications, sans carte. Pro coûte 19 $ par mois pour jusqu'à cinq serveurs et un nombre illimité d'applications. Team coûte 49 $ par mois avec des serveurs illimités. Aucuns frais par application, par déploiement, par siège ou par gigaoctet.
- Des gabarits en un clic. Déployez des applications open source, comme des bases de données, des outils d'analyse et des outils de développement, sur votre propre serveur en un clic.
- Des bases de données gérées. Postgres, MySQL et Redis, avec des sauvegardes planifiées, vérifiées par restauration, et la récupération à un point dans le temps.
- Déploiement par push. Déployez depuis GitHub, GitLab ou la CLI, avec HTTPS automatique et des mises en production sans interruption.