n8n + PostgreSQL en self-hosted : automatiser ses workflows

Bannière : n8n et PostgreSQL en self-hosted

n8n est un outil d'automatisation de workflows (façon Zapier/Make) que l'on peut héberger soi-même, avec un éditeur visuel et la possibilité d'écrire du code JavaScript custom dans les cas complexes. Couplé à PostgreSQL plutôt qu'à la base SQLite par défaut, il tient sans souci une charge de production avec plusieurs dizaines de workflows actifs.

1. docker-compose.yml

docker-compose.yml
services:
  postgres:
    image: postgres:16
    container_name: postgres-n8n
    restart: unless-stopped
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=change-moi
      - POSTGRES_DB=n8n
    volumes:
      - ./postgres:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n -d n8n"]
      interval: 5s
      retries: 10

  n8n:
    image: n8nio/n8n:stable
    container_name: n8n
    restart: unless-stopped
    ports:
      - "5678:5678"
    environment:
      - N8N_HOST=votredomaine.com
      - N8N_PROTOCOL=https
      - N8N_SECURE_COOKIE=true
      - WEBHOOK_URL=https://votredomaine.com/
      - GENERIC_TIMEZONE=Europe/Paris
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres-n8n
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=change-moi
      - NODE_FUNCTION_ALLOW_BUILTIN=net,crypto
    volumes:
      - ./data:/home/node/.n8n
      - ./files:/files
    depends_on:
      postgres:
        condition: service_healthy
Piège de version : sur un moteur Docker ancien, les images n8n récentes ("Docker Hardened Images") peuvent échouer avec failed to register layer: invalid tar header. Si ça arrive, épinglez une version antérieure connue plutôt que latest. Idem côté Postgres : la version 18 a changé la structure de ses dossiers de données par version majeure, incompatible avec un montage de volume classique — restez en 16 sauf migration volontaire et testée.

2. La variable NODE_FUNCTION_ALLOW_BUILTIN

Par défaut, les nœuds Code de n8n n'ont accès à aucun module Node.js natif, pour des raisons de sécurité. Si vos workflows ont besoin du réseau (net, par exemple pour un scan de ports) ou de signatures cryptographiques (crypto, pour authentifier une requête API type HMAC), il faut les autoriser explicitement :

.env
NODE_FUNCTION_ALLOW_BUILTIN=net,crypto

Cette variable remplace la liste des modules autorisés, elle ne l'étend pas : si un futur workflow a besoin d'un module supplémentaire, il faut le rajouter dans la même liste plutôt que de croire qu'il s'ajoute automatiquement aux précédents.

3. Reverse proxy

Pointez la destination de votre reverse proxy vers localhost (ou le nom du conteneur si le proxy tourne lui-même en Docker sur le même réseau) plutôt que vers une IP fixe interne, pour éviter les problèmes de routage lors d'une recréation de conteneur. Le support WebSocket doit être activé (n8n l'utilise pour l'éditeur de workflow en temps réel).

4. OAuth (Gmail, Google...) en self-hosted

Pour connecter un nœud Gmail en OAuth, il faut créer des identifiants dans Google Cloud Console (API Gmail activée, identifiants "Application Web"). Point d'attention : Google refuse les URI de redirection en IP brute ou en localhost pour une application en production — utilisez un nom de domaine, même auto-hébergé.

Bonne pratique réseau : si plusieurs stacks Docker (n8n, Grafana, une autre application) doivent communiquer entre elles, faites-les cohabiter sur le même réseau Compose nommé plutôt que de router par IP interne — les IP changent à chaque recréation du réseau, les noms de conteneurs non.

Conclusion

n8n en self-hosted avec Postgres tient très bien la charge pour un usage personnel ou une petite structure. L'essentiel des soucis rencontrés viennent du pinning de version (à ne jamais laisser en latest sans tester) et des permissions des nœuds Code — une fois ces deux points maîtrisés, la plateforme est remarquablement stable.

R
Raph — Chronoassistance25 ans d'expérience en informatique, cybersécurité et infrastructure.