Guida

Come fare il self-hosting di n8n su un VPS

Questa guida installa n8n su un VPS Linux con Docker Compose, Postgres e HTTPS, poi affronta le decisioni che arrivano dopo: quando attivare la queue mode, cosa includere nei backup e come aggiornare senza perdere le credenziali. Numeri di versione, nomi delle variabili e limiti sono presi dalla documentazione di n8n così come appare a novembre 2026. Controlla le pagine linkate prima di fare affidamento su un dettaglio, perché n8n cambia in fretta.

Di team EvorxaPubblicata il

Cosa consente la licenza

n8n in self-hosting è pubblicato con la Sustainable Use License, una licenza fair-code che n8n ha scritto nel 2022. Ti permette di usare, modificare e ridistribuire il software gratuitamente, con tre limiti: puoi usarlo solo per i tuoi scopi aziendali interni o per uso non commerciale e personale; puoi darlo ad altri solo gratuitamente e per scopi non commerciali; e non puoi rimuovere gli avvisi di licenza o di copyright di n8n.

La frase che risolve la maggior parte dei casi è la prima delle FAQ sulla licenza di n8n: se i workflow vengono creati o modificati solo da te o da persone della tua organizzazione, puoi usare la licenza Community gratuitamente.

Consentito con la licenza Community

  • Usarlo per gestire la tua attività, oltre che per progetti personali, apprendimento o ricerca.
  • Creare automazioni per i clienti sulla tua istanza, purché i clienti non possano crearle o modificarle.
  • Farti pagare dai clienti per creare, configurare e mantenere i workflow, e per formazione e consulenza.
  • Usare n8n dietro le quinte nel tuo prodotto, dove gli utenti avviano automazioni che hai creato tu e collegano persino i propri account.
  • Eseguire più istanze.

Non consentito senza un accordo commerciale

  • Offrire n8n in hosting come servizio in cui sono i tuoi clienti a creare i workflow.
  • Permettere a utenti esterni di creare o configurare i propri workflow tramite il tuo prodotto, che sia attraverso la tua interfaccia, l'API, MCP o un agente IA che agisce per loro conto.
  • Fare un fork del codice per lanciare un tuo prodotto di automazione, oppure rivendere n8n in white label rimuovendone il marchio.
  • Usare funzioni enterprise che richiedono una chiave di licenza senza avere una licenza Enterprise.

Se il tuo progetto sta a metà tra le due liste, n8n ti chiede di scrivere a license@n8n.io prima di realizzarlo.

Quanto deve essere grande il server

n8n consuma poca CPU. La sua pagina dei prerequisiti dice che i requisiti di memoria di solito contano più della CPU, e che un'istanza n8n Cloud inattiva usa circa 100 MB. Ciò che fa salire la memoria è il lavoro stesso: payload JSON grandi, file binari come PDF e immagini, molti nodi in un solo workflow, il nodo Code e le esecuzioni di test manuali, che tengono una copia in più dei dati per l'editor.

Dimensioni indicate dalla documentazione di n8n
ConfigurazioneValore documentatoDa dove viene
n8n inattivoCirca 100 MB di RAMPagina dei prerequisiti, n8n Cloud inattivo
Processo n8n, intervallo tipicoDa 320 MB a 2 GB di RAMPagina dei prerequisiti
Spazio per il databaseDa 512 MB a 4 GB di SSDPagina dei prerequisiti
Stack Compose completo con la sandbox di n8n AssistantAlmeno 4 GB di RAM e 2 vCPUGuida all'installazione con Docker Compose

Al valore di n8n aggiungi Postgres, il reverse proxy e il sistema operativo. Il numero su cui pianificare è il picco durante il tuo workflow più pesante, non il valore a riposo: esegui quel workflow una volta sul nuovo server e osserva docker stats mentre gira. Se pensi di eseguire la sandbox di n8n Assistant dal file Compose ufficiale, considera 4 GB e 2 vCPU come minimo.

Docker Compose con Postgres

Di base n8n salva tutto in SQLite. La guida a Docker Compose dice che SQLite va bene per fare prove, ma un'istanza di produzione con più di una manciata di utenti, o con workflow attivi a ciclo continuo, dovrebbe usare Postgres. La queue mode non supporta affatto SQLite, quindi partire con Postgres ti evita una migrazione in seguito.

Installa Docker Engine con il plugin Compose, crea una cartella come ~/n8n e mettici dentro due file. Prima il file .env. Fissa N8N_VERSION a un numero di release reale preso dalla pagina delle release di n8n su GitHub, e genera tu la chiave di cifratura, così che sia annotata da qualche parte oltre che sul server:

.env
# .env (keep it out of version control)
N8N_VERSION=2.xx.x
N8N_HOST=n8n.example.com
N8N_ENCRYPTION_KEY=change-me-long-random-string
POSTGRES_USER=n8n
POSTGRES_PASSWORD=change-me-password
POSTGRES_DB=n8n
GENERIC_TIMEZONE=Europe/Amsterdam

Poi compose.yaml:

compose.yaml
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:${N8N_VERSION}
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    environment:
      N8N_HOST: ${N8N_HOST}
      N8N_PORT: 5678
      N8N_PROTOCOL: https
      NODE_ENV: production
      N8N_WEBHOOK_URL: https://${N8N_HOST}/
      N8N_PROXY_HOPS: 1
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
      TZ: ${GENERIC_TIMEZONE}
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: 5432
      DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
      DB_POSTGRESDB_USER: ${POSTGRES_USER}
      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  db-storage:
  n8n_data:
  • Mantieni la riga PGDATA. Postgres 18 ha cambiato la posizione predefinita dei dati e, senza quella riga, il database viene scritto fuori dal volume e riparte vuoto quando il container viene ricreato.
  • La porta 5678 è collegata a 127.0.0.1, quindi solo il reverse proxy sullo stesso server può raggiungere n8n. Verso internet devono essere aperte solo la 80 e la 443.
  • Il volume n8n_data in /home/node/.n8n conta anche con Postgres: contiene il file della chiave di cifratura, i log e gli asset del source control.

Avvialo con docker compose up -d. n8n crea le sue tabelle in Postgres al primo avvio. I dati di una precedente istanza SQLite non vengono trasferiti da soli; esporta workflow e credenziali con i comandi CLI della sezione sui backup e importali.

HTTPS, il reverse proxy e gli URL dei webhook

n8n costruisce gli URL dei webhook a partire da N8N_PROTOCOL, N8N_HOST e N8N_PORT. Dietro un proxy questo dà il risultato sbagliato, perché n8n ascolta sulla 5678 mentre l'URL pubblico è sulla 443. La pagina sul reverse proxy chiede tre cose:

  1. Imposta N8N_WEBHOOK_URL sull'indirizzo pubblico, per esempio https://n8n.example.com/. Ha sostituito WEBHOOK_URL, deprecata a partire da n8n 2.35.0. Nelle versioni precedenti alla 2.30.0, usa WEBHOOK_URL.
  2. Imposta N8N_PROXY_HOPS=1 quando davanti a n8n c'è un solo proxy.
  3. Fai in modo che l'ultimo proxy passi X-Forwarded-For, X-Forwarded-Host e X-Forwarded-Proto.

Va bene qualsiasi proxy che faccia queste tre cose. Con Caddy l'intera configurazione è di quattro righe. La direttiva reverse_proxy di Caddy imposta tutti e tre gli header forwarded e inoltra le connessioni WebSocket senza impostazioni aggiuntive, e Caddy richiede da solo il certificato per il dominio non appena il DNS punta al server:

Caddyfile
# /etc/caddy/Caddyfile
n8n.example.com {
    reverse_proxy 127.0.0.1:5678
}

Se nell'editor i webhook mostrano localhost:5678, o i servizi esterni rifiutano l'URL, manca N8N_WEBHOOK_URL oppure il container non è stato ricreato dopo che l'hai impostata. Esegui di nuovo docker compose up -d dopo ogni modifica all'ambiente.

Queue mode: quando servono Redis e i worker

Nella modalità predefinita un solo processo n8n serve l'editor, riceve i webhook ed esegue ogni workflow. Basta per la maggior parte delle istanze usate da un singolo team. Due segnali che non basta più: le esecuzioni si accumulano dietro quelle di lunga durata, oppure l'editor smette di rispondere mentre girano workflow pesanti.

Prova prima la soluzione economica. N8N_CONCURRENCY_PRODUCTION_LIMIT limita quante esecuzioni di produzione girano contemporaneamente e mette in coda le altre; è disattivata per impostazione predefinita. Se un solo processo resta il collo di bottiglia, la queue mode divide il lavoro: il processo principale riceve trigger e webhook, Redis contiene la coda e i processi worker eseguono le esecuzioni.

aggiunte a compose.yaml
# 1. in the n8n service: name the environment block, add the queue settings
    environment: &n8n-env
      # ...everything from before, plus:
      EXECUTIONS_MODE: queue
      QUEUE_BULL_REDIS_HOST: redis
      QUEUE_BULL_REDIS_PORT: 6379
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started

# 2. two new services
  redis:
    image: redis:7
    restart: always

  n8n-worker:
    image: n8nio/n8n:${N8N_VERSION}
    restart: always
    command: worker --concurrency=10
    environment: *n8n-env
    depends_on:
      - postgres
      - redis
  • Ogni processo ha bisogno della stessa N8N_ENCRYPTION_KEY, delle stesse impostazioni del database e della stessa versione dell'immagine.
  • Un worker esegue 10 job alla volta per impostazione predefinita. n8n consiglia 5 o più per worker: molti worker con concorrenza bassa possono esaurire il pool di connessioni del database.
  • La queue mode con SQLite non è supportata, e i dati binari non possono restare sul filesystem locale; per questo n8n rimanda allo storage esterno S3.
  • Per un traffico webhook intenso, aggiungi dei processori webhook (n8n webhook) e imposta N8N_DISABLE_PRODUCTION_MAIN_PROCESS=true sul processo principale. Eseguire più processi principali richiede una licenza Enterprise.

Backup che possono ripristinare le credenziali

Un backup completo ha due parti, secondo la pagina su backup e ripristino di n8n: la cartella .n8n, che contiene la chiave di cifratura, e il database Postgres. Le credenziali nel database sono cifrate con quella chiave, quindi un dump del database senza la chiave non può ripristinarle.

shell
# workflows and credentials as JSON, one file each
docker compose exec n8n n8n export:workflow --backup --output=/home/node/.n8n/backups/workflows/
docker compose exec n8n n8n export:credentials --backup --output=/home/node/.n8n/backups/credentials/

# the whole Postgres database
docker compose exec -T postgres pg_dumpall -U n8n > n8n-db-$(date +%F).sql
  • Il flag --backup scrive ogni workflow e ogni credenziale in un file JSON separato. Usa cartelle diverse per workflow e credenziali; l'importazione delle credenziali fallisce quando i file dei workflow stanno nella stessa cartella.
  • Le esportazioni CLI escludono utenti, cronologia delle esecuzioni, variabili e impostazioni dell'istanza, chiave compresa. Servono a spostare workflow tra istanze, non a ricostruirne una.
  • Copia il dump, le esportazioni e il volume .n8n fuori dal server. Un backup sullo stesso disco non sopravvive alla perdita del server.
  • I workflow importati arrivano disattivati. Metti in conto di riattivarli dopo un ripristino.

Aggiornare senza sorprese

La pagina sugli aggiornamenti di n8n suggerisce di aggiornare almeno una volta al mese, così non salti mai molte versioni in una volta, e di leggere le note di rilascio di ogni versione tra la tua e quella di destinazione.

shell
# 1. back up first (see above), then set the new N8N_VERSION in .env
docker compose pull
docker compose up -d
docker compose logs -f n8n

Fai prima il backup completo. Ogni processo esegue le migrazioni del database in sospeso quando si avvia, e riportare il tag dell'immagine alla vecchia versione non le annulla. Tornare indietro significa eseguire n8n db:revert una migrazione alla volta con l'immagine più recente, oppure ripristinare il backup. In queue mode, aggiorna insieme processo principale, worker e processori webhook allo stesso tag.

Errori comuni e soluzioni

Sintomi e la loro causa abituale
Cosa vediCausa probabileCosa fare
"Execution stopped at this node (n8n may have run out of memory while executing it)", "Connection Lost" o errori 503Il processo ha esaurito la memoria e si è riavviatoDividi i dati in batch (200 righe invece di 10.000), sposta i passaggi pesanti in sub-workflow, evita il nodo Code e le esecuzioni manuali con grandi quantità di dati
"Allocation failed - JavaScript heap out of memory" nei logRaggiunto il limite dell'heap di Node.jsAlzalo con NODE_OPTIONS (vedi sotto) se il server ha RAM libera, oppure aggiungi RAM
Gli URL dei webhook mostrano localhost o la porta sbagliataN8N_WEBHOOK_URL non impostata o container non ricreatoImpostala sull'URL HTTPS pubblico ed esegui docker compose up -d
Le credenziali non si decifrano dopo uno spostamentoChiave di cifratura diversaRipristina la cartella .n8n originale o imposta la N8N_ENCRYPTION_KEY originale
Postgres si chiude con "database files are incompatible with server"Immagine passata a una nuova versione major su una vecchia cartella datiTorna al vecchio tag, esegui pg_dumpall, poi segui la guida all'aggiornamento di PostgreSQL
Il disco continua a riempirsiCronologia delle esecuzioniLa pulizia automatica è attiva per impostazione predefinita (14 giorni o 10.000 esecuzioni); abbassa EXECUTIONS_DATA_MAX_AGE o EXECUTIONS_DATA_PRUNE_MAX_COUNT

Le soluzioni per la memoria vengono dalla pagina di n8n sugli errori legati alla memoria. Alzare il limite dell'heap si fa così:

compose.yaml
# n8n service environment: raise the Node.js heap limit (value in MB)
      NODE_OPTIONS: --max-old-space-size=2048

Eseguirlo su Evorxa

Tutto quanto descritto sopra funziona su un server Evorxa, con accesso root e SSH. Puoi partire da un'immagine Ubuntu o Debian pulita, di solito pronta in circa un minuto, oppure scegliere l'app n8n one-click, che richiede qualche minuto in più per l'installazione. I piani partono da $2.99 al mese e sono prepagati su base mensile, semestrale o annuale. I server girano in una sola regione, Eygelshoven nei Paesi Bassi.

Fonti

I fatti di questa guida provengono da queste pagine.

  1. n8n: Sustainable Use License e FAQ sulla licenza
  2. n8n: installazione con Docker Compose (sezione Postgres)
  3. n8n: configurare gli URL dei webhook con un reverse proxy
  4. n8n: attivare la queue mode
  5. n8n: backup e ripristino
  6. n8n: errori legati alla memoria