n8n in Docker dietro Cloudflare Tunnel: la mia architettura completa
Yuri Perfetti5 min1 letturaTempo di lettura: 8 minuti — Livello: intermedio
Perché questo setup
n8n è il cuore delle mie automazioni: parser di email, bot Telegram, sincronizzazioni tra knowledge base, monitoraggio news. Tutto self-hosted, per tre motivi: controllo dei dati, nessun limite di esecuzioni, costo zero oltre l'hardware che già possiedo.
Ma self-hosted significa un problema classico: come esponi n8n su internet (serve per i webhook e per gli OAuth) senza aprire porte sul router di casa? La risposta che uso da tempo: Cloudflare Tunnel.
L'architettura in un colpo d'occhio
Internet
│
▼
Cloudflare (DNS + certificato HTTPS + protezione)
│
▼ tunnel cifrato in uscita
cloudflared (connettore sul mio server)
│
▼ http://localhost:5678
Container Docker n8n
│
├── volume n8n_data (database, credenziali, encryption key)
└── network dedicata (per parlare con gli altri container)
Il punto chiave: il tunnel è una connessione in uscita dal mio server verso Cloudflare. Nessuna porta aperta in ingresso, nessun port forwarding sul router, il mio IP di casa non è esposto da nessuna parte. Per il mondo esterno esiste solo n8n.miodominio.it, che vive sull'infrastruttura di Cloudflare.
Pezzo 1: il container n8n
Uso un'immagine custom (ci torno tra un attimo), ma la struttura del run è questa:
docker run -d --name n8n \
--restart unless-stopped \
--network n8n-network \
-v n8n_data:/home/node/.n8n \
--env-file /percorso/n8n.env \
-p 127.0.0.1:5678:5678 \
la-tua-immagine-n8n
Tre scelte deliberate:
Il volume nominato (n8n_data) contiene il database SQLite, i workflow e — attenzione — la encryption key con cui n8n cifra tutte le credenziali salvate. La chiave vive nel volume, non nell'env file. Se distruggi il volume, le tue credenziali diventano illeggibili per sempre. È il pezzo da proteggere e backuppare.
La network dedicata (n8n-network) permette a n8n di parlare con gli altri container per nome. Nel mio caso, per esempio, un microservizio di generazione documenti Word: n8n lo chiama come http://docx-service:3000 e Docker risolve tutto internamente, senza esporre nulla.
L'env file esterno tiene fuori dal comando (e dalla history della shell) le variabili sensibili: URL dei webhook, chiavi API, configurazione proxy. Un file, un posto solo da modificare.
⚠️ La regola che mi sono scritto in grande dopo un incidente: quando ricrei il container, ricordati SEMPRE --network e --env-file. Un docker run frettoloso senza quei due flag produce un n8n che parte, sembra sano, e poi fallisce in modi misteriosi: i webhook puntano all'URL sbagliato, i container vicini non rispondono. Tenete il comando completo in un file di note e copiatelo da lì, sempre.
Pezzo 2: perché un'immagine custom
L'immagine ufficiale di n8n va benissimo per iniziare. Io sono passato a una custom per un motivo preciso: i moduli npm esterni. Alcuni miei workflow usavano librerie come docxtemplater per generare documenti Word, e per permetterne l'uso nei nodi Code serve la variabile NODE_FUNCTION_ALLOW_EXTERNAL più i pacchetti installati nell'immagine.
(Nota per chi è su n8n 2.x: il nuovo task runner ha reso questa strada molto più rigida. Io alla fine ho spostato la generazione documenti in un microservizio separato — ne ho scritto un articolo dedicato. La versione corta: quando combatti contro la piattaforma, spesso la risposta è un container in più, non una configurazione in più.)
Pezzo 3: il tunnel
Cloudflare Tunnel si può gestire in due modi: da file di configurazione o dalla dashboard Zero Trust. Io uso la seconda: crei il tunnel dall'interfaccia web, ti dà un token, avvii il connettore cloudflared con quel token, e da lì in poi la mappatura hostname → servizio la gestisci dal browser.
La mappatura nel mio caso è semplice:
n8n.miodominio.it → http://localhost:5678
Cloudflare termina l'HTTPS, quindi il certificato non lo gestisco io: rinnovi automatici, zero Let's Encrypt, zero cron job.
Le due trappole di questo setup
-
n8n non sa di essere dietro un proxy. Il tunnel inoltra il traffico in HTTP verso localhost, e n8n — se non glielo dici — genera URL interni sbagliati. Il sintomo più famoso: OAuth di Google che fallisce con "Unauthorized". La cura sono quattro variabili d'ambiente da impostare insieme, e ci ho dedicato un articolo intero la settimana scorsa.
-
Le protezioni di Cloudflare possono bloccare il TUO traffico. Cloudflare offre protezioni contro bot e scraper, inclusa una specifica per gli "AI bots". Ottima idea, finché non colleghi un client MCP al tuo n8n e scopri che la tua stessa protezione sta bloccando la tua integrazione. Se qualcosa che passa dal tunnel fallisce in modo strano, i log di Cloudflare (sezione Security) sono il primo posto dove guardare.
Manutenzione: quello che faccio davvero
- Backup del volume prima di ogni aggiornamento: docker run --rm -v n8n_data:/data -v $(pwd):/backup alpine tar czf /backup/n8n_backup.tar.gz /data
- Aggiornamenti: mai a caldo, mai di venerdì. Nuova immagine, stop, rm, run con il comando completo salvato nelle note
- Test post-aggiornamento: un workflow di "canarino" con un webhook che chiamo a mano per verificare che il giro completo internet → tunnel → n8n funzioni
Vale la pena?
Per me sì, e tanto. Il costo di gestione reale, superata la configurazione iniziale, è di qualche minuto al mese. In cambio ho una piattaforma di automazione senza limiti, raggiungibile da ovunque, con i miei dati a casa mia. Il compromesso vero è un altro: sei tu il tuo sysadmin. Se questa frase ti suona come una minaccia più che come una promessa, n8n cloud esiste apposta.
Questo articolo fa parte della serie "Stack & Infrastruttura" su perfetti.tech — dove racconto quello che costruisco davvero, errori compresi.
Hai un problema simile?
Mandami due righe: ti dico se ha senso trasformarlo in uno strumento vero e quanto tempo serve.
Scrivimi →Commenti
Ancora nessun commento. Scrivi il primo!