← Home
Automazione 📅 6 giugno 2026 ⏱️ 15 minuti di lettura ✍️ Nicola Petriccione

n8n self-hosted con Docker: setup produzione GDPR per PMI

Installare n8n in 30 minuti è facile. Tenerlo in produzione per anni — con backup verificati, HTTPS, aggiornamenti senza downtime e un registro trattamenti che regge un audit GDPR — è un'altra storia. In questa guida trovi l'architettura Docker production-ready che usiamo nei deployment DN8lab per PMI italiane da 1 a 10M€ di fatturato: queue mode con Redis, PostgreSQL, hardening del server, disaster recovery e checklist di conformità completa.

In questa guida

1. Setup "demo" vs setup produzione: le differenze che contano

La maggior parte dei tutorial online ti porta a un n8n funzionante con un singolo comando docker run. Quel setup usa SQLite come database, gira senza HTTPS, non ha backup, e processa i workflow nello stesso processo dell'interfaccia web. Va benissimo per provare la piattaforma. Va malissimo per farci girare la fatturazione della tua azienda.

Le differenze tra demo e produzione si pagano nei momenti peggiori. SQLite si corrompe se il container viene killato durante una scrittura. Senza HTTPS, le credenziali delle tue integrazioni (Google, Stripe, il gestionale) viaggiano in chiaro. Senza queue mode, un workflow pesante che elabora 200 PDF blocca l'interfaccia per tutti. E senza backup testati, un errore umano — un docker volume rm sbagliato — cancella due anni di automazioni.

Un setup produzione per PMI richiede cinque componenti: PostgreSQL come database (transazionale, robusto, backuppabile a caldo), Redis per il queue mode (separazione tra interfaccia e workers), reverse proxy con HTTPS automatico (Caddy o Traefik), backup automatici off-site, e monitoring di base. Tutto questo gira comodamente su un VPS da 8-15€/mese — non serve Kubernetes, non serve un cluster, non serve un DevOps a tempo pieno.

Questa guida assume che tu conosca già n8n come piattaforma. Se non è così, parti dalla nostra guida completa a n8n per PMI italiane e torna qui quando sei pronto al deploy.

2. Scegliere il VPS: requisiti e confronto provider EU

Per la conformità GDPR il primo requisito non è tecnico ma geografico: il server deve stare in un data center dell'Unione Europea, gestito da un provider con DPA solido. Questo elimina alla radice il problema dei trasferimenti transfrontalieri per i dati che n8n processa internamente.

I requisiti hardware minimi per un n8n produzione con queue mode su una PMI tipo (10-30 workflow attivi, qualche migliaio di esecuzioni/giorno):

Confronto tra provider europei adatti a questo carico (prezzi di listino indicativi a giugno 2026, IVA esclusa):

Provider Piano indicativo Specifiche Prezzo/mese Data center Note
Hetzner CX32 4 vCPU / 8 GB / 80 GB ~7€ Germania, Finlandia Miglior rapporto prezzo/prestazioni in EU
Hostinger KVM 2 2 vCPU / 8 GB / 100 GB ~8-12€ Lituania, Francia, Germania Pannello semplice, buono per chi inizia
OVHcloud VPS Comfort 4 vCPU / 8 GB / 160 GB ~12€ Francia, Germania, Polonia Provider francese, certificazioni enterprise
Aruba Cloud VPS L 4 vCPU / 8 GB / 80 GB ~15€ Italia (Arezzo, Ponte S. Pietro) Data center in Italia: argomento forte con DPO conservativi

La nostra scelta di default è Hetzner per il rapporto qualità/prezzo, oppure Aruba quando il cliente vuole poter dire "i dati stanno fisicamente in Italia". Tutti e quattro offrono DPA conformi all'art. 28 GDPR scaricabili dal sito.

3. Architettura production-ready: n8n + PostgreSQL + Redis

L'architettura che deployiamo è composta da cinque container orchestrati da Docker Compose:

  1. n8n main — serve l'interfaccia web, gestisce i trigger (webhook, cron) e accoda i job
  2. n8n worker — esegue i workflow prelevandoli dalla coda; puoi scalarne il numero
  3. PostgreSQL 16 — persistenza di workflow, credenziali (cifrate), esecuzioni
  4. Redis 7 — broker della coda job (queue mode)
  5. Caddy — reverse proxy con HTTPS automatico via Let's Encrypt

Il queue mode (variabile EXECUTIONS_MODE=queue) è la differenza più importante rispetto al setup base. Nel setup base, interfaccia ed esecuzioni condividono lo stesso processo Node.js: un workflow che satura la CPU rende l'interfaccia inutilizzabile e, peggio, può far perdere webhook in arrivo. In queue mode il processo main resta leggero e reattivo, mentre i worker macinano i job in parallelo. Se il carico cresce, aggiungi worker con una riga di configurazione — senza toccare nient'altro.

Le credenziali sono cifrate at-rest con AES-256 usando la N8N_ENCRYPTION_KEY: una chiave che generi tu al primo avvio e che devi custodire fuori dal server (password manager aziendale). Senza quella chiave, il backup del database è illeggibile — il che è un bene per la sicurezza e un disastro se la perdi.

Quanto regge questa architettura?

Su un VPS 4 vCPU / 8 GB con 2 worker, abbiamo misurato in produzione picchi di 10.000+ esecuzioni/giorno con workflow misti (API call, parsing PDF, nodi AI) senza degrado percepibile. Per una PMI da 1-10M€ di fatturato c'è margine per anni di crescita prima di dover pensare a scalare orizzontalmente.

4. Il docker-compose.yml completo (commentato)

Questo è il file che usiamo come base nei deployment reali. Crea una directory /opt/n8n, salva il file e un .env a fianco con i segreti.

# /opt/n8n/docker-compose.yml
x-n8n-common: &n8n-common
  image: n8nio/n8n:latest
  restart: unless-stopped
  environment: &n8n-env
    - N8N_HOST=n8n.tuodominio.it
    - N8N_PROTOCOL=https
    - WEBHOOK_URL=https://n8n.tuodominio.it/
    - GENERIC_TIMEZONE=Europe/Rome
    - TZ=Europe/Rome
    # --- Database ---
    - DB_TYPE=postgresdb
    - DB_POSTGRESDB_HOST=postgres
    - DB_POSTGRESDB_DATABASE=n8n
    - DB_POSTGRESDB_USER=n8n
    - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
    # --- Queue mode ---
    - EXECUTIONS_MODE=queue
    - QUEUE_BULL_REDIS_HOST=redis
    - OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true
    # --- Sicurezza ---
    - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
    - N8N_BLOCK_ENV_ACCESS_IN_NODE=true
    # --- GDPR: pruning esecuzioni (vedi sez. 7) ---
    - EXECUTIONS_DATA_PRUNE=true
    - EXECUTIONS_DATA_MAX_AGE=720          # 30 giorni, in ore
    - EXECUTIONS_DATA_PRUNE_MAX_COUNT=50000
  depends_on:
    - postgres
    - redis

services:
  n8n:
    <<: *n8n-common
    ports:
      - "127.0.0.1:5678:5678"   # esposto SOLO su localhost: fuori c'è Caddy
    volumes:
      - n8n_data:/home/node/.n8n

  n8n-worker:
    <<: *n8n-common
    command: worker
    deploy:
      replicas: 2               # scala qui i worker

  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=n8n
    volumes:
      - pg_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: redis-server --maxmemory 256mb --maxmemory-policy noeviction

volumes:
  n8n_data:
  pg_data:

E il file .env (permessi 600, mai committato in git):

# /opt/n8n/.env
POSTGRES_PASSWORD=$(openssl rand -base64 32)   # genera e incolla il valore
N8N_ENCRYPTION_KEY=$(openssl rand -base64 32)  # SALVALA nel password manager

Tre dettagli che fanno la differenza: il binding 127.0.0.1:5678 impedisce l'accesso diretto alla porta n8n dall'esterno (tutto passa dal reverse proxy); N8N_BLOCK_ENV_ACCESS_IN_NODE impedisce ai nodi Code di leggere le variabili d'ambiente (e quindi i segreti); il pruning delle esecuzioni tiene il database sotto controllo ed è anche un requisito di minimizzazione GDPR.

5. HTTPS e hardening del server

Caddy resta la via più rapida per l'HTTPS automatico. Installalo come pacchetto di sistema e configura il Caddyfile:

n8n.tuodominio.it {
    reverse_proxy localhost:5678
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
    }
}

Sul fronte hardening del server, il minimo sindacale per un host che processa dati aziendali:

Preferisci che il setup lo faccia chi lo fa ogni settimana?

Deployiamo n8n production-ready per PMI italiane: server hardened, backup testati, documentazione GDPR inclusa. Prenota una call gratuita di 20 minuti e ti diciamo costi e tempi per il tuo caso.

Prenota una call gratuita →

6. Backup e disaster recovery

Il backup di un n8n production ha tre componenti, e dimenticarne uno rende inutili gli altri due:

  1. Il database PostgreSQL — workflow, credenziali cifrate, storico esecuzioni
  2. Il volume n8n_data — configurazione dell'istanza e, nei setup più vecchi, la encryption key
  3. La N8N_ENCRYPTION_KEY — senza di lei, le credenziali nel backup del database sono irrecuperabili

Script di backup giornaliero con dump a caldo e retention 14 giorni, da agganciare a cron:

#!/usr/bin/env bash
# /opt/n8n/backup.sh — cron: 0 2 * * *
set -euo pipefail
TS=$(date +%F)
BK=/opt/backups/n8n
mkdir -p "$BK"

# 1. Dump PostgreSQL a caldo (nessun downtime)
docker compose -f /opt/n8n/docker-compose.yml exec -T postgres \
  pg_dump -U n8n n8n | gzip > "$BK/n8n-db-$TS.sql.gz"

# 2. Volume dati n8n
docker run --rm -v n8n_n8n_data:/data -v "$BK":/bk alpine \
  tar czf "/bk/n8n-data-$TS.tar.gz" -C /data .

# 3. Copia off-site su storage S3-compatibile EU (es. Hetzner Object Storage)
rclone copy "$BK" remote-eu:n8n-backups --max-age 24h

# Retention locale: 14 giorni
find "$BK" -mtime +14 -delete

Due regole non negoziabili. Primo: il backup off-site deve stare su infrastruttura diversa dal VPS — se l'account del provider viene compromesso o cancellato, i backup sulla stessa macchina muoiono col server. Un bucket S3-compatibile in EU costa pochi euro al mese. Secondo: un backup non testato non è un backup. Una volta a trimestre, fai un restore completo su un VPS temporaneo e verifica che i workflow girino e le credenziali si decifrino. Mettilo a calendario: 30 minuti che possono salvare l'azienda.

7. GDPR: data residency, log retention e registro trattamenti

Self-hosted in EU non significa automaticamente GDPR-compliant. Significa che hai il controllo necessario per esserlo. I punti da sistemare in pratica:

7.1 Minimizzazione: pruning dei log di esecuzione

Ogni esecuzione n8n salva di default l'intero payload dei dati processati: se il workflow elabora fatture, nel database restano nomi, partite IVA, importi — per sempre, se non intervieni. Le variabili EXECUTIONS_DATA_PRUNE e EXECUTIONS_DATA_MAX_AGE (nel compose sopra: 30 giorni) implementano il principio di limitazione della conservazione (art. 5.1.e). Trenta giorni è un buon equilibrio tra esigenze di debugging e minimizzazione; per workflow che trattano categorie particolari di dati, valuta di salvare solo le esecuzioni in errore (savedataonsuccess: none a livello di singolo workflow).

7.2 Registro dei trattamenti: mappa i nodi che escono dal perimetro

Il punto più sottovalutato: anche con n8n self-hosted, ogni nodo che chiama un'API esterna è un trasferimento di dati. Un workflow che manda il testo delle fatture a Claude API trasferisce dati personali ad Anthropic (USA, con SCC e DPA). Uno che scrive su Google Sheets li trasferisce a Google. Per ogni workflow in produzione, documenta nel registro dei trattamenti (art. 30): quali dati entrano, quali nodi li mandano a terzi, dove sono quei terzi, e con quale base contrattuale (DPA + SCC). Un export JSON del workflow allegato alla scheda di trattamento è documentazione eccellente per un audit.

7.3 Diritti degli interessati e sicurezza

Se un interessato esercita il diritto di cancellazione (art. 17), i suoi dati potrebbero stare anche nei log delle esecuzioni n8n: con il pruning a 30 giorni il problema si risolve da solo entro la finestra; senza pruning, devi cercarli a mano nel database. Sul fronte misure tecniche (art. 32): la combinazione cifratura credenziali AES-256 + HTTPS + accessi nominali con 2FA + backup cifrati off-site copre quello che un auditor si aspetta di trovare su un sistema di questa classe.

⚠️ Il nodo AI è il punto critico dell'audit

Nel 2026, la prima domanda di qualunque DPO riguarda i nodi AI: "che dati mandate al modello e dove vengono processati?". Tieni pronta la risposta: elenco dei workflow con nodi AI, tipologia di dati inviati, DPA del provider, ed eventuale anonimizzazione/pseudonimizzazione a monte (un nodo Code che maschera nomi e P.IVA prima della chiamata API costa 20 minuti di lavoro e semplifica enormemente la compliance).

8. Aggiornamenti e manutenzione ordinaria

n8n rilascia versioni minor ogni settimana. In produzione non si usa latest alla cieca: pinna una versione specifica nel compose (es. n8nio/n8n:1.97.1) e aggiorna deliberatamente, ogni 2-4 settimane, leggendo le release notes — le breaking changes sono rare ma esistono, specialmente sui nodi community.

Procedura di aggiornamento sicura (downtime: ~30 secondi):

# 1. Backup pre-aggiornamento
/opt/n8n/backup.sh

# 2. Aggiorna il tag versione nel docker-compose.yml, poi:
cd /opt/n8n
docker compose pull
docker compose up -d        # ricrea solo i container cambiati

# 3. Verifica
docker compose logs -f n8n --tail 50
# controlla che le migrazioni DB siano andate a buon fine

Completa la manutenzione un monitoring minimo: un workflow n8n schedulato che ogni ora verifica lo stato dell'istanza via /healthz non basta (se n8n è giù, non gira nemmeno lui) — serve un check esterno. Un monitor gratuito tipo UptimeRobot o un cron su un'altra macchina che chiama https://n8n.tuodominio.it/healthz e notifica su Telegram copre il 90% dei casi reali: server pieno, certificato scaduto, container in crash loop.

9. Checklist finale pre-produzione

Prima di dichiarare l'istanza "in produzione", verifica ogni punto:

Se tutti i punti sono verdi, hai un'istanza n8n che può far girare processi business-critical per anni con poche ore di manutenzione al mese. Se alcuni punti ti sembrano oscuri o non hai le competenze interne per gestirli, è esattamente il tipo di lavoro che facciamo per i nostri clienti: prenota una call gratuita o scrivici a info@dn8lab.it — analizziamo il tuo caso e ti diciamo in 20 minuti se e come possiamo aiutarti.

NP
Nicola Petriccione

Ingegnere, fondatore di DN8lab e Sintech Solution. Aiuta PMI italiane ad automatizzare processi operativi con AI e workflow engine. Napoli, Italia.