Risposta diretta
Per installare n8n con Docker Compose servono tre file: docker-compose.yml, un file .env per le variabili sensibili e un volume montato per la persistenza dei dati. Con questi tre elementi il container parte, sopravvive ai riavvii e non perde i workflow se il server si spegne.
Self-hostare n8n su Docker è la scelta che fanno quasi tutti quelli che vogliono controllo sui dati, costi fissi e nessun limite di esecuzioni imposto da un piano cloud. Il percorso non è complicato, ma ogni passaggio tralasciato si paga dopo — in silenzio, senza messaggi di errore. Questa guida copre l’installazione completa con Docker Compose, la configurazione minima per andare in produzione e le guardie che separano un setup che regge da uno che si rompe alla prima ripartenza.
Perché Docker Compose e non l’installazione diretta di n8n
Installare n8n via npm install -g n8n funziona sul laptop. Su un server condiviso, con aggiornamenti da gestire e processi che devono restare vivi, diventa un problema in tre settimane. Docker isola il processo, fissa la versione e rende il rollback una questione di un numero nel file di configurazione.
Docker Compose aggiunge un livello in più: descrive l’intera macchina in un file di testo versionabile. Vuoi spostare n8n su un nuovo server? Copi il file e il volume. Vuoi aggiungere un database Postgres invece di SQLite? Aggiungi un servizio nel compose. La complessità non sparisce, ma diventa leggibile.
Su n8n: la guida ufficiale all’installazione con Docker trovi i requisiti minimi ufficiali. Il punto di partenza è quello; questa guida aggiunge quello che la documentazione ufficiale non dice esplicitamente: cosa succede quando si rompe.
Prerequisiti prima di scrivere il primo file
Serve un server — VPS, macchina locale o cloud instance — con almeno 1 GB di RAM libera e Docker Engine installato. La versione di Docker Compose integrata nei pacchetti recenti di Docker Desktop è sufficiente; se usi un VPS Linux, controlla con docker compose version (senza il trattino: la sintassi vecchia docker-compose è deprecata).
Serve un dominio o un sottodominio puntato all’IP del server se vuoi HTTPS. Senza HTTPS i webhook di n8n funzionano, ma nessun servizio esterno serio accetta endpoint HTTP in chiaro nel 2024. Cloudflare Tunnel è un’alternativa valida se non vuoi gestire certificati a mano.
Serve sapere dove metti i file. Scegli una directory fissa — /opt/n8n è una convenzione ragionevole su Linux — e non cambiare mai path a setup avviato, a meno che tu non voglia ricostruire i riferimenti ai volumi.

Struttura dei file per n8n Docker Compose
Lavora con questa struttura minima:
/opt/n8n/
├── docker-compose.yml
├── .env
└── data/ ← volume persistente
Il file docker-compose.yml
Questo è il file che descrive il servizio. La versione base con SQLite — sufficiente per workflow fino a qualche centinaio di esecuzioni al giorno — è questa:
services:
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- '5678:5678'
environment:
- N8N_HOST=${N8N_HOST}
- N8N_PORT=5678
- N8N_PROTOCOL=${N8N_PROTOCOL}
- NODE_ENV=production
- WEBHOOK_URL=${WEBHOOK_URL}
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
volumes:
- ./data:/home/node/.n8n
Tre cose da non tralasciare. restart: unless-stopped fa ripartire il container dopo un reboot del server senza intervento manuale. Il volume ./data:/home/node/.n8n monta la directory locale dentro il container: senza di questo, ogni docker compose down cancella workflow e credenziali. N8N_ENCRYPTION_KEY cifra le credenziali salvate; se lo perdi o lo cambi, le credenziali esistenti diventano illeggibili.
Il file .env
Non mettere valori sensibili direttamente nel compose. Usa il file .env nella stessa directory:
N8N_HOST=n8n.tuodominio.com
N8N_PROTOCOL=https
WEBHOOK_URL=https://n8n.tuodominio.com/
GENERIC_TIMEZONE=Europe/Rome
N8N_ENCRYPTION_KEY=una-stringa-lunga-e-casuale-almeno-32-caratteri
Il file .env va in .gitignore se il progetto è su un repo. Non è negoziabile: N8N_ENCRYPTION_KEY in un repo pubblico espone tutte le credenziali integrate nei workflow.
La regola
Un’automazione senza persistenza non è in produzione
Se il volume non è montato correttamente, i workflow sopravvivono al container ma non al server. La prima volta che fai un aggiornamento e riscrivi il container, perdi tutto. Verifica il mount prima di costruire un solo workflow.
- Volume montato — controlla con docker inspect che il path locale esista davvero sul disco
- Encryption key — annotala in un posto sicuro fuori dal server, non solo nel .env
- Restart policy — unless-stopped è diverso da always: lascia spento il container se lo fermi tu a mano
Avvio e verifica dell’installazione n8n con Docker Compose
Dalla directory /opt/n8n esegui:
docker compose up -d
Il flag -d avvia in background. I log in tempo reale si leggono con docker compose logs -f n8n. Nei primi avvii n8n scrive il database, inizializza le tabelle e stampa l’URL su cui è in ascolto. Se vedi Editor is now accessible via: http://localhost:5678 il container gira.
Se hai un reverse proxy (Nginx o Traefik), il porto 5678 non deve essere esposto pubblicamente: il proxy gestisce HTTPS sul 443 e passa il traffico al container in rete interna. La configurazione del reverse proxy esula da questa guida, ma la documentazione ufficiale di n8n per Docker Compose include esempi con Traefik già integrato nel compose.
Aggiornare n8n senza perdere dati
L’aggiornamento si riduce a tre comandi:
docker compose pull
docker compose down
docker compose up -d
Se il volume è montato correttamente, i workflow restano intatti. Prima di ogni aggiornamento maggiore, fai un backup manuale della directory data/: cp -r /opt/n8n/data /opt/n8n/data-backup-YYYYMMDD. Non è elegante, ma ha fermato perdite di dati che un sistema senza backup non avrebbe recuperato.

Postgres invece di SQLite: quando ha senso
SQLite è un file su disco. Regge bene fino a qualche centinaio di esecuzioni al giorno su workflow non concorrenti. Quando i workflow aumentano, le esecuzioni si sovrappongono e i log crescono, SQLite comincia a mostrare lock sulle scritture.
La migrazione a Postgres si fa aggiungendo un secondo servizio nel compose:
services:
postgres:
image: postgres:15
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: n8n
volumes:
- ./postgres-data:/var/lib/postgresql/data
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
depends_on:
- postgres
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
# ... resto delle variabili
La migrazione da un’istanza SQLite esistente non è automatica: i dati storici non si trasferiscono. Se parti da zero, usa Postgres subito. Se hai già workflow in produzione su SQLite, valuta se i log storici ti servono davvero prima di migrare.
Le guardie che separano un setup serio da uno che si rompe in silenzio
Un container che gira non è un sistema che funziona. Il silenzio dei log non è salute: è il sintomo che nessuno sta guardando.
Le guardie minime per un’istanza n8n in produzione sono quattro. Prima: un backup automatico della directory dati, almeno giornaliero, su storage esterno (S3, Backblaze, anche un secondo VPS). Seconda: un monitor di uptime esterno — BetterStack o simili — che batta sull’URL di n8n ogni minuto e ti manda un messaggio se non risponde. Terza: i workflow critici devono avere un nodo di gestione errori collegato, che scriva il fallimento da qualche parte leggibile — un foglio, un canale Slack, un record nel CRM. Quarta: tieni traccia della versione in uso nel .env o in un file VERSION nella directory: quando un aggiornamento rompe qualcosa, sapere da quale versione stai facendo il rollback vale ore di debug.
Un’automazione senza queste guardie esegue sbagliato con la stessa sicurezza con cui esegue giusto. Non rallenta, non dubita, non ti chiama.
Parti con n8n
Inizia con la struttura giusta, non con quella che sistemi dopo
I primi giorni su n8n self-hosted sono quelli in cui si prendono le abitudini che poi si portano in produzione. Costruisci la macchina bene dal primo giorno.
- Fase 1 — Installa con Docker Compose seguendo questa guida, verifica il volume e annota l’encryption key
- Fase 2 — Crea un workflow di test con un webhook e verifica che sopravviva a un docker compose down e up
- Fase 3 — Aggiungi il monitor di uptime e il backup automatico prima di costruire qualsiasi workflow che tocchi dati reali
Apri il piano gratuito di Make →
Link di affiliazione: se ti iscrivi da qui io prendo una commissione, tu paghi uguale. Lo linko perché ci lavoro dentro ogni giorno.
Errori comuni nell’installazione n8n con Docker Compose
Il volume non monta perché la directory data/ non esiste prima del primo avvio. Docker la crea, ma a volte la crea con permessi root. Il container n8n gira come utente node (UID 1000) e non riesce a scrivere. Fix: mkdir -p /opt/n8n/data && chown -R 1000:1000 /opt/n8n/data prima del primo docker compose up.
I webhook non arrivano perché WEBHOOK_URL punta a localhost invece che al dominio pubblico. n8n usa quella variabile per costruire gli URL che comunica ai servizi esterni. Se è sbagliata, i servizi chiamano un endpoint irraggiungibile e non ricevi nessun dato — nessun errore, nessun log, solo silenzio.
Le credenziali diventano illeggibili dopo un aggiornamento perché N8N_ENCRYPTION_KEY è cambiata o non è stata impostata nel nuovo ambiente. La chiave deve essere identica a quella con cui i dati sono stati cifrati. Senza di essa, ogni integrazione va riconfigurata da zero.
Se vuoi approfondire quanto costa gestire n8n in cloud rispetto al self-hosting, ho analizzato i piani in dettaglio in questo articolo sui costi di n8n. E se stai valutando n8n rispetto ad altri strumenti, la guida completa a n8n in italiano copre il confronto con Make e le architetture più comuni.
Per chi viene da un approccio no-code e sta valutando se il self-hosting è la strada giusta, la lettura utile è cos’è n8n e perché sta crescendo: mette in contesto la scelta prima di scendere nella configurazione.
Docker Compose risolve il problema dell’installazione. Non risolve il problema del sistema. La macchina parte in dieci minuti; farla reggere in produzione richiede le guardie giuste, un backup che hai testato almeno una volta e la disciplina di non toccare variabili critiche senza un piano di rollback. Chi salta questi passaggi li ritrova nel momento peggiore — un workflow fermo, un cliente che aspetta dati e nessun log che spiega perché.
Domande frequenti
Posso usare n8n con Docker Compose su Windows o Mac?
Sì. Docker Desktop su Windows e Mac astrae il sistema operativo: il compose funziona allo stesso modo. In sviluppo locale va bene; per la produzione usa sempre un VPS Linux — la gestione dei permessi sui volumi è più prevedibile e il consumo di risorse è inferiore.
Quanta RAM serve per far girare n8n con Docker?
Il minimo dichiarato è 1 GB, ma con SQLite e workflow non concorrenti reggono tranquillamente istanze con 512 MB di RAM assegnata al container. Con Postgres nello stesso host servono almeno 2 GB totali per lavorare senza swap continuo.
Come faccio il backup dei workflow senza accesso al database?
n8n ha un endpoint REST che esporta tutti i workflow in JSON: GET /api/v1/workflows con l’API key dell’istanza. Puoi costruire un workflow n8n che si esegue ogni notte, chiama quell’endpoint e salva il JSON su S3. La macchina fa il backup di sé stessa.
Se aggiorno l’immagine Docker, perdo i workflow?
No, se il volume è montato correttamente. I workflow sono nel database dentro data/, non nel layer del container. L’immagine è solo il codice applicativo; i dati stanno sul disco dell’host. Verifica il mount con docker inspect prima di fare il primo aggiornamento.
Trasparenza: in questo articolo c’è un link di affiliazione. Se ti iscrivi da lì io ricevo una commissione, per te non cambia niente. Linko solo strumenti che uso in produzione.


