Migrare da n8n Cloud a self-hosted su un VPS europeo: guida con DPA e GDPR
Quando ha senso lasciare n8n Cloud, come scegliere provider e DPA in Europa, cosa esportare prima, il Docker Compose con Postgres e TLS, le variabili degli URL, i webhook da aggiornare e lo switch in parallelo. Con la tabella di cosa migra da solo e cosa va rifatto.

Quando ha senso lasciare n8n Cloud?
Ha senso in tre casi: superi le 2.500 esecuzioni al mese del piano Starter e il piano Pro non basta o costa troppo; i workflow trattano dati personali di clienti o dipendenti e vuoi un solo responsabile del trattamento, europeo, con DPA firmato; i limiti di memoria del piano bloccano i workflow con file. Se nessuno in azienda può gestire un server, resta sul Cloud e sistema gli adempimenti descritti in n8n Cloud e GDPR. Se invece uno dei tre casi è il tuo, questa è la sequenza che seguiamo noi.
Quale provider europeo e quale DPA?
Il vantaggio principale del self-hosted sul fronte GDPR è la catena corta: un solo responsabile esterno del trattamento, il fornitore del server, con un DPA che firmi tu. Perché la catena resti corta, il fornitore deve essere una società europea con data center in UE:
| Provider | Sede | Data center UE | DPA | Note |
|---|---|---|---|---|
| Hetzner | Germania | Falkenstein, Norimberga, Helsinki | Si firma dalla console del cliente (in tedesco AVV) | Miglior rapporto qualità prezzo, guida ufficiale n8n con Caddy |
| OVHcloud | Francia | Gravelines, Roubaix, Strasburgo | Allegato alle condizioni contrattuali | Utile se hai già un contratto quadro |
| Scaleway | Francia | Parigi, Amsterdam, Varsavia | Nei documenti contrattuali dell'area cliente | Buona offerta di storage S3 europeo per i backup |
Per un'istanza n8n con Postgres bastano 2 vCPU e 4 GB di RAM: i numeri per piano li trovi nel costo reale di n8n self-hosted. Prima di creare il server, scarica il DPA del provider e mettilo nel fascicolo del registro dei trattamenti: il fornitore del server sostituisce n8n GmbH come responsabile esterno, e la privacy policy va aggiornata di conseguenza.
Cosa esportare dal Cloud prima di iniziare?
Dal Cloud escono i workflow, non le credenziali. Hai tre strade per i workflow:
- Dashboard di amministrazione: Admin Dashboard, sezione Manage, scheda Export, pulsante Download Workflows. Scarica i workflow dall'ultimo backup dell'istanza.
- Editor: menu del singolo workflow, voce Download. Utile per rifare un export puntuale dopo una modifica dell'ultimo minuto.
- Pacchetti n8n (in anteprima): con la n8n CLI e una API key,
n8n-cli package export --project-id=... --output=cloud.n8npporta workflow, cartelle, tag, variabili con i loro valori e le tabelle dati. È il metodo più completo, ma il formato può ancora cambiare.
Le credenziali invece vanno inventariate a mano. Nell'editor apri la sezione Credentials e annota per ciascuna: nome, tipo, quali workflow la usano. La documentazione ufficiale è esplicita: i segreti delle credenziali non viaggiano mai in un pacchetto, che contiene solo ID, nome e tipo. Tieni gli stessi nomi sull'istanza nuova, così l'import le riaggancia per nome e tipo invece di creare segnaposto vuoti. Le connessioni OAuth (Google, Microsoft, HubSpot) vanno comunque riautorizzate, perché l'URL di callback cambia con il dominio.
Un promemoria di tempi: se sei ancora in trial, hai 90 giorni dalla scadenza per scaricare i workflow, poi vengono cancellati.
Come preparare il server con Docker Compose, Postgres e TLS?
La base è la stessa della guida ufficiale per Hetzner: Docker Compose, Postgres e Caddy come reverse proxy, che ottiene e rinnova da solo il certificato Let's Encrypt. Versione bloccata, mai latest:
services:
postgres:
image: postgres:18
restart: always
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
PGDATA: /var/lib/postgresql/data
volumes:
- db-storage:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 10
n8n:
image: n8nio/n8n:2.37.7
restart: always
env_file: .env
depends_on:
postgres:
condition: service_healthy
volumes:
- n8n_data:/home/node/.n8n
caddy:
image: caddy:2
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
volumes:
db-storage:
n8n_data:
caddy_data:
Il Caddyfile è una riga di sostanza: n8n.example.com { reverse_proxy n8n:5678 { flush_interval -1 } }. La porta 5678 non va pubblicata sull'host: è raggiungibile solo da Caddy sulla rete interna di Compose. Il file .env contiene le variabili di Postgres, la N8N_ENCRYPTION_KEY generata da te e le variabili degli URL.
Quali variabili fanno funzionare gli URL?
Dietro un reverse proxy n8n deve sapere con quale indirizzo pubblico viene raggiunto, altrimenti genera URL di webhook e di callback OAuth sbagliati:
N8N_HOST=n8n.example.com
N8N_PORT=5678
N8N_PROTOCOL=https
N8N_EDITOR_BASE_URL=https://n8n.example.com/
N8N_WEBHOOK_URL=https://n8n.example.com/
N8N_PROXY_HOPS=1
GENERIC_TIMEZONE=Europe/Rome
TZ=Europe/Rome
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
N8N_DIAGNOSTICS_ENABLED=false
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
DB_POSTGRESDB_USER=${POSTGRES_USER}
DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
Due note. WEBHOOK_URL, il nome storico che trovi in molte guide, dalla 2.35.0 è un alias deprecato di N8N_WEBHOOK_URL: funziona ancora, ma n8n scrive un avviso a ogni avvio. N8N_DIAGNOSTICS_ENABLED=false spegne la telemetria anonima verso n8n: è coerente con il motivo per cui stai migrando. Dopo il primo avvio verifica che l'istanza risponda e che la versione sia quella bloccata:
docker compose up -d
docker compose exec n8n n8n --version
curl -s https://n8n.example.com/healthz
Come importare i workflow e aggiornare i webhook?
Importa i JSON scaricati dal Cloud con la CLI interna, che per default lascia tutti i workflow non pubblicati. È esattamente quello che vuoi durante la migrazione:
docker compose exec -u node n8n mkdir -p /home/node/.n8n/import
docker cp ./cloud-export/. "$(docker compose ps -q n8n)":/home/node/.n8n/import/
docker compose exec -u node n8n n8n import:workflow --separate --input=/home/node/.n8n/import/
Poi crea le credenziali con gli stessi nomi del Cloud, apri ogni workflow e riassegna quelle che risultano mancanti. I webhook cambiano solo nella base dell'URL:
| Prima (n8n Cloud) | Dopo (self-hosted) |
|---|---|
https://tua-istanza.app.n8n.cloud/webhook/ordine-nuovo | https://n8n.example.com/webhook/ordine-nuovo |
https://tua-istanza.app.n8n.cloud/webhook-test/ordine-nuovo | https://n8n.example.com/webhook-test/ordine-nuovo |
Il percorso finale resta uguale perché è salvato nel JSON del workflow. La base va invece aggiornata in ogni servizio che chiama n8n: Stripe, WooCommerce, i moduli del sito, il CRM, i trigger delle app che registrano il webhook da sole (per queste ultime basta disattivare e riattivare il trigger sull'istanza nuova).
Come testare in parallelo e fare lo switch?
Per un paio di giorni le due istanze convivono. Sul self-hosted esegui a mano ogni workflow con dati di prova, usando l'URL webhook-test per quelli a webhook, e verifica che l'esito sia identico a quello del Cloud. I workflow con Schedule Trigger restano pubblicati su una sola istanza per volta, altrimenti l'ordine parte due volte.
Lo switch, workflow per workflow: pubblica sul self-hosted, aggiorna l'URL nel servizio esterno, spubblica sul Cloud, controlla la prima esecuzione reale nei log. Chi ha molti webhook fa lo switch in blocco in una finestra concordata, tenendo il Cloud spubblicato ma vivo per una settimana come rete di sicurezza.
Cosa migra da solo e cosa va rifatto?
| Migra da solo | Va rifatto a mano |
|---|---|
| Workflow: nodi, connessioni, espressioni, impostazioni | Credenziali, con gli stessi nomi del Cloud |
| Percorsi dei webhook | Base degli URL webhook nei servizi esterni |
| Variabili con i valori (solo con i pacchetti n8n) | Connessioni OAuth: da riautorizzare sul nuovo dominio |
| Cartelle, tag, tabelle dati (solo con i pacchetti n8n) | Utenti, ruoli e condivisioni |
| Nomi e ID delle credenziali (come riferimenti) | Nodi community: da reinstallare prima dell'import |
| Storico delle esecuzioni e cronologia delle versioni: non si trasferiscono | |
| Registro dei trattamenti, privacy policy, DPA con il nuovo provider |
Cosa fare del piano Cloud?
Dopo una settimana di esercizio pulito sul self-hosted: scarica un ultimo export dei workflow dalla dashboard, come copia storica, poi annulla l'abbonamento e cancella l'istanza dall'area di amministrazione. Non lasciare l'istanza Cloud viva con i workflow spubblicati: contiene ancora le credenziali e i dati delle esecuzioni, e nel registro dei trattamenti risulterebbe un responsabile che di fatto non usi più. Aggiorna il registro e la privacy policy nello stesso giorno.
E il server?
La migrazione sposta n8n, ma da questo momento il server è tuo: chi lo aggiorna, chi guarda i log di Caddy e di Postgres, chi fa i backup dell'istanza e li prova, chi riceve l'alert alle tre di notte se il disco è pieno. Se in azienda non c'è nessuno per questo, puoi affidare la migrazione del server e la sua gestione a un servizio esterno, con DPA e compliance della gestione già formalizzati, tenendo n8n dove preferisci.
Il perimetro resta netto: n8n.it segue l'istanza n8n, i workflow e le integrazioni; managedvps.it segue il server sotto, dal sistema operativo al firewall. Se vuoi una mano a pianificare la migrazione o a rifare l'inventario delle credenziali, contattaci.
Consulenti n8n.it
Consulenza indipendente su n8n
Siamo consulenti indipendenti focalizzati su automazione dei processi aziendali e sicurezza delle implementazioni n8n self-hosted.
Articoli correlati

Aggiornare n8n in produzione senza rompere i workflow
Perché il tag latest non va in produzione, come leggere release notes e breaking changes, il pin del...
Leggi di più
Backup di n8n self-hosted: cosa salvare, come, e come provare il ripristino
Cosa contiene davvero la cartella dati di n8n, perché la chiave di cifratura è l'unico pezzo che non...
Leggi di più
Proteggere un sito WordPress con n8n: monitoraggio integrità, alert e risposta
Come usare n8n per monitorare un sito WordPress: checksum del core, file PHP sospetti negli upload, ...
Leggi di più