Samen Steeve
MES SERVICES.
Retour au blog
DevOpsDockerAutomatisationn8nInfrastructure
Déployer n8n en production sur un VPS partagé : retour d'expérience
21 juillet 20267 min de lecture

Déployer n8n en production sur un VPS partagé : retour d'expérience

L'outil d'automatisation autopilote peut lui-même mal tourner : une mauvaise isolation sur un VPS partagé, et c'est votre base de production qui paie les frais. Voici comment j'ai déployé n8n en production pour le projet TribuneJustice— une plateforme legaltech que j'ai construite de A à Z et que je pilote — sans rien casser de l'infrastructure existante.

Le contexte : rentabiliser un VPS déjà en place

Sur TribuneJustice, j'avais besoin d'un orchestrateur de tâches récurrentes : notifications, synchronisations entre services, jobs planifiés. Plutôt que de payer un abonnement cloud facturé à l'exécution, j'ai choisi d'auto-héberger n8n sur un VPS déjà utilisé pour le projet — histoire de rentabiliser des ressources disponibles plutôt que de multiplier les infrastructures.

Le VPS tournait déjà sous Ubuntu, avec Docker, nginx, Redis et une base MySQL locale. L'objectif : ajouter n8n proprement, via un sous-domaine dédié, sans affecter la disponibilité du reste.

L'architecture retenue : isolation complète

La tentation était de faire cohabiter n8n avec la base MySQL de production. J'ai refusé — un crash ou une saturation de disque côté n8n aurait eu un impact direct sur le site principal. L'architecture retenue repose sur une isolation stricte :

— Un conteneur PostgreSQL 16 dédié (n8n recommande officiellement Postgres, pas MySQL, en production)
— Un réseau Docker isolé reliant uniquement n8n et sa base
— n8n exposé uniquement sur 127.0.0.1:5678, jamais directement sur internet
— Le nginx existant configuré avec un server_block dédié pour n8n.samensteeve.com
— Des limites CPU/mémoire sur les conteneurs pour ne pas empiéter sur le projet principal

Cette isolation garantit qu'un problème sur n8n (crash, faille, usage disque excessif) n'affecte jamais la disponibilité du site principal ni l'intégrité de sa base de données.

Le déploiement, étape par étape

1. Préparer l'arborescence dédiée

Terminal — Bash
Bash
sudo mkdir -p /opt/n8n
cd /opt/n8n
sudo mkdir -p n8n_data postgres_data

2. Générer la clé de chiffrement

Cette clé chiffre tous les credentials stockés par n8n (mots de passe d'API, tokens OAuth).

Terminal — OpenSSL
Secret
openssl rand -hex 32

3. Fichier de variables d'environnement

.env
Config
N8N_HOST=n8n.samensteeve.com
N8N_PROTOCOL=https
N8N_WEBHOOK_URL=https://n8n.samensteeve.com/
N8N_ENCRYPTION_KEY=<clé générée à l'étape précédente>
GENERIC_TIMEZONE=Africa/Douala
TZ=Africa/Douala

DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=n8n_user
DB_POSTGRESDB_PASSWORD=<mot de passe fort>

POSTGRES_USER=n8n_user
POSTGRES_PASSWORD=<le même mot de passe fort>
POSTGRES_DB=n8n

4. Définir le docker-compose.yml

docker-compose.yml
Docker
services:
  postgres:
    image: postgres:16-alpine
    container_name: n8n_postgres
    restart: always
    env_file: .env
    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

  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: always
    env_file: .env
    ports:
      - "127.0.0.1:5678:5678"
    volumes:
      - ./n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - n8n_net

networks:
  n8n_net:
    driver: bridge

5. Reverse Proxy Nginx & SSL Let's Encrypt

/etc/nginx/sites-available/n8n.samensteeve.com
Nginx
server {
    listen 80;
    server_name n8n.samensteeve.com;

    location / {
        proxy_pass http://127.0.0.1:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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;
    }
}

Ce que le déploiement "propre" ne dit pas : le debugging réel

La théorie d'un déploiement Docker + nginx + SSL est bien documentée. La pratique, sur un serveur qui vit déjà, l'est moins. Voici les trois incidents rencontrés et comment je les ai résolus.

1. Erreur de permissions sur le volume monté

Error: EACCES: permission denied, open '/home/node/.n8n/config'

Le processus n8n dans le conteneur tourne sous l'UID 1000 (utilisateur node), mais le dossier créé côté hôte appartenait à root. Diagnostic : chown -R 1000:1000 sur le volume a résolu le blocage.

2. Le sous-domaine flaggé "site dangereux" par Google

Le plus instructif des trois. Une fois le service opérationnel et le HTTPS activé, Chrome s'est mis à bloquer brutalement l'accès au sous-domaine avec un avertissement rouge d'hameçonnage — alors que le contenu était parfaitement légitime.

Avertissement Google Safe Browsing - Site Dangereux sur n8n.samensteeve.com
Figure 1 : Blocage heuristique Chrome / Google Safe Browsing lors du premier accès au sous-domaine n8n.

En creusant (Google Search Console, forums communautaires n8n), j'ai découvert un pattern documenté : une page de connexion nue, sur un sous-domaine tout neuf, derrière un CDN, correspond statistiquement au profil d'une page de phishing pour les classifieurs heuristiques de Google Safe Browsing.

La résolution a nécessité une démarche administrative plutôt que technique : validation de la propriété du domaine via Search Console, puis demande de révision manuelle auprès des équipes Google.

3. Victoire : l'instance n8n opérationnelle en production

Une fois le faux positif levé par Google et les permissions de volumes corrigées, l'instance n8n est enfin accessible de manière sécurisée et prête à orchestrer nos automatisations.

Dashboard n8n en ligne - Que veux-tu construire Sam ?
Figure 2 : Interface n8n sécurisée et opérationnelle sur n8n.samensteeve.com.

Ce qui tourne en production aujourd'hui

L'instance n8n est déployée et sécurisée sur n8n.samensteeve.com (2FA, sauvegardes PostgreSQL automatisées). Le Lead Qualification Agent y tourne en production, connecté au WhatsApp CRM Assistant (construit et testé) par une même Data Table CRM — le cœur du système.

Lead Qualification Agent (écriture) — en production

Agent IA autonome qui intercepte les soumissions de formulaire, enrichit les données via Tavily, score le lead de 1 à 10, et écritdans la CRM Data Table (upsert par email). Email de notification personnalisé envoyé au prospect en < 30 secondes. Mémoire Redis, Output Parser strict (schéma JSON contraint), retry sur Gmail et Tavily. Webhook sécurisé par header + filtrage IP — le workflow est publié et reçoit les soumissions de formulaire.

WhatsApp CRM Assistant (lecture & opérationnel) — en attente de credentials

Agent WhatsApp qui permet de lireet interroger la même CRM en langage naturel — consulter les leads récents, chercher par email, mettre à jour un statut, envoyer un email professionnel. Mémoire Redis pour le contexte conversationnel. Construit et testé en manuel ; la publication n'attend que les credentials WhatsApp Business.

Le pipeline complet

Les deux workflows forment un système unifié : le Lead Agent peuple la CRM avec des leads qualifiés et enrichis, le WhatsApp Assistant permet de consulter et agirsur ces données directement depuis WhatsApp — sans ouvrir l'interface n8n. Mémoire Redis partagée pour la continuité conversationnelle entre les deux agents.

— Chaque workflow a sa propre logique de sécurité : Header Auth (n8n-webhook-secret) pour le Lead Agent, authentification WhatsApp Business pour le CRM Assistant (une fois ses credentials renseignées).
retryOnFail configuré sur les nœuds critiques (Gmail, Tavily, HTTP).
— Mémoire Redis partagée pour la persistance conversationnelle.

La sécurisation finale & Ce que je retiens

2FA activée sur le compte administrateur
Backups automatisés (dump PostgreSQL quotidien) via script cron, rotation sur 7 jours
— Compte owner verrouillé après création — tout nouvel utilisateur doit être invité explicitement

Ce type de déploiement — modeste en apparence — mobilise tout un spectre de compétences : architecture système (isolation, réseaux Docker), sécurité (permissions, chiffrement, authentification), réseau (DNS, reverse proxy, certificats SSL), et une méthode rigoureuse pour diagnostiquer des pannes réelles.

Un projet technique critique ?

Vous cherchez un ingénieur expérimenté pour concevoir votre architecture, auditer votre code ou intégrer de l'IA ?

Démarrer un projet