Torna al blog
n8n Self-Hosted: Automazioni Concrete tra Database, API e LLM

n8n Self-Hosted: Automazioni Concrete tra Database, API e LLM

9 min di lettura2 visualizzazioni
di Marco Salmaso
Zapier e Make vanno bene finché i volumi sono bassi e i dati non sono sensibili. Quando colleghi un database aziendale, un LLM locale e qualche API interna, il self-hosting di n8n cambia le regole. Vediamo come impostare workflow concreti, con esempi di nodi, codice e gestione degli errori.

Mi occupo di dati e automazioni in un'azienda retail con sei negozi. Negli ultimi mesi ho spostato molte delle piccole integrazioni che tenevo in piedi con script Python sparsi dentro un unico strumento: n8n self-hosted. Non è una bacchetta magica, ma risolve un problema molto concreto: far parlare tra loro gestionale, database, fogli di calcolo, LLM e API interne senza scrivere ogni volta un servizio da zero e senza affidare dati sensibili a un SaaS esterno.

In questo articolo racconto come lo uso e quali sono i punti su cui vale la pena ragionare prima di adottarlo.

Cos'è n8n e perché self-hosted

n8n è un tool di automazione a workflow visuale: colleghi nodi, ognuno dei quali fa qualcosa (leggere una tabella, chiamare un'API, trasformare un JSON, inviare una mail), e li fai girare su trigger o su schedule. La differenza rispetto a Zapier o Make è duplice.

La prima è il prezzo: il modello è a workflow/nodi illimitati sul self-hosted, mentre le alternative cloud fatturano a "task" eseguiti. Se hai una sync che gira ogni 5 minuti e processa centinaia di record, i costi esplodono rapidamente.

La seconda, più importante nel mio caso, è la sovranità sui dati. I dati di vendita, i nomi dei clienti, le fatture, non escono dalla mia infrastruttura. n8n gira su un container Docker sul NAS o su una VM, e l'unica cosa che esce è ciò che decido io.

Detto questo: n8n non è un orchestratore dati serio come Airflow o Dagster. Non ha la stessa gestione delle dipendenze, dei backfill, della lineage. È più vicino a un "coltellino svizzero delle integrazioni" che a un data pipeline framework. Va usato per quello che è.

Il modello mentale: trigger, nodi, esecuzioni

Un workflow in n8n è composto da:

  • un trigger (cron, webhook, evento da un'altra app, chiamata manuale);
  • una serie di nodi collegati, ognuno con input e output;
  • una esecuzione, cioè una singola run del workflow, con la sua history di input/output per ogni nodo.

Il punto che all'inizio mi confondeva è che ogni nodo ragiona in termini di lista di item, non di singolo oggetto. Questo è potentissimo ma va capito: se un nodo SQL restituisce 200 righe, il nodo successivo viene chiamato 200 volte (una per item), non una volta con la lista. Ci sono nodi ricombinanti — come Merge, Split In Batches, Code — che servono proprio a gestire questo.

Una volta entrato in testa questo modello, il resto è disegno.

Tre automazioni che uso davvero

Per non restare sul teorico, ecco tre workflow che nel mio caso valgono il tempo speso a montarli.

1. Sync incrementale da gestionale a PostgreSQL

Il gestionale espone alcune tabelle via REST. Un workflow gira ogni 15 minuti con un trigger Schedule, legge dal gestionale le righe modificate dall'ultima esecuzione (uso un timestamp salvato in una tabella di stato), e fa un upsert su PostgreSQL.

Il nodo SQL si scrive direttamente nel workflow. Esempio di upsert su una tabella vendite:

INSERT INTO vendite (id, data, negozio_id, articolo_id, quantita, importo)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT (id) DO UPDATE SET
  data = EXCLUDED.data,
  quantita = EXCLUDED.quantita,
  importo = EXCLUDED.importo,
  updated_at = NOW();

Con n8n si può usare il nodo Postgres con parametri posizionali, oppure passare un'intera riga come JSON. La seconda è più comoda quando i campi cambiano.

Il vantaggio rispetto a uno script Python è che la logica di retry, logging e notifica su errore è già nel tool. Se una notte l'API del gestionale è giù, il workflow ritenta con backoff e mi manda un avviso su Telegram solo se fallisce tre volte di fila.

2. Alert su KPI di negozio

Un workflow gira ogni mattina alle 7:30, esegue una query che confronta le vendite del giorno precedente con la media mobile degli ultimi 28 giorni per negozio, e notifica solo dove lo scostamento supera una certa soglia.

La query di esempio (i valori sono solo per capire la struttura):

WITH ultimo_giorno AS (
  SELECT negozio_id, SUM(importo) AS venduto_ieri
  FROM vendite
  WHERE data = CURRENT_DATE - 1
  GROUP BY negozio_id
),
baseline AS (
  SELECT negozio_id,
         AVG(importo_giornaliero) AS media_28gg,
         STDDEV(importo_giornaliero) AS sd_28gg
  FROM (
    SELECT negozio_id, data, SUM(importo) AS importo_giornaliero
    FROM vendite
    WHERE data BETWEEN CURRENT_DATE - 29 AND CURRENT_DATE - 2
    GROUP BY negozio_id, data
  ) t
  GROUP BY negozio_id
)
SELECT u.negozio_id, u.venduto_ieri, b.media_28gg,
       (u.venduto_ieri - b.media_28gg) / NULLIF(b.sd_28gg, 0) AS z_score
FROM ultimo_giorno u
JOIN baseline b USING (negozio_id)
WHERE ABS((u.venduto_ieri - b.media_28gg) / NULLIF(b.sd_28gg, 0)) > 2;

Quello che esce viene formattato e, se non è vuoto, inviato. Se è vuoto, il workflow si ferma silenziosamente. Una regola che mi sono dato: un alert che arriva anche quando va tutto bene è un alert che nessuno guarda più.

3. Ingestion di documenti per un RAG interno

Questo è il workflow che mi ha convinto di più. Mettiamo una cartella condivisa dove finiscono manuali, procedure, listini. Un trigger su file system intercetta nuovi PDF, il workflow:

  1. estrae il testo (nodo PDF);
  2. lo divide in chunk (nodo Code con una funzione di split);
  3. chiama un modello di embedding in locale — nel mio caso un servizio esposto da Ollama;
  4. salva i vettori su pgvector, insieme ai metadati (filename, pagina, timestamp).

Il codice del nodo Code per lo split può essere banale:

const testo = $input.first().json.testo;
const dimensione = 800;
const overlap = 100;
const chunks = [];
for (let i = 0; i < testo.length; i += dimensione - overlap) {
  chunks.push({ json: { testo: testo.slice(i, i + dimensione) } });
}
return chunks;

Il resto è un nodo HTTP Request verso l'endpoint degli embedding e un nodo Postgres con INSERT su una tabella documenti_embeddings. Niente di esoterico: è la stessa cosa che faresti in Python, ma visibile e modificabile senza riavviare un servizio.

Quando il visuale non basta: codice e HTTP

Due nodi, secondo me, sono quelli che fanno la differenza tra un giocattolo e uno strumento serio.

Il nodo Code esegue JavaScript (o Python, in alcuni setup) con accesso a tutti gli item in ingresso. Serve per trasformazioni che con i nodi standard diventerebbero un labirinto di 12 passaggi. Io lo uso per normalizzare formati data, pulire stringhe, costruire payload complessi.

Il nodo HTTP Request è la porta verso qualsiasi cosa abbia un'API: il gestionale, un servizio interno, un LLM, un webhook di Slack. Configuri metodo, URL, header, body e gestisci la risposta. Con autenticazione via credenziali salvate (che restano cifrate nel database di n8n), non hai token in chiaro sparse nei workflow.

Aggiungo una cosa pratica: non tutto va fatto con nodi. Se una trasformazione è complessa, a volte conviene scrivere un piccolo servizio Python a parte e chiamarlo via HTTP. n8n come orchestratore, non come contenitore di tutta la logica.

Schedule, retry, errori: le cose che contano in produzione

La parte che si sottovaluta sempre è la gestione degli errori. In n8n si configura per ogni nodo:

  • Retry On Fail con numero di tentativi e attesa;
  • Continue On Fail, utile per non far cadere tutto il workflow per un singolo item problematico;
  • Error Workflow, cioè un workflow separato che scatta quando un altro fallisce.

Nel mio caso l'Error Workflow manda un messaggio con: nome del workflow, nodo che ha fallito, messaggio di errore e link all'esecuzione. Fine. Non serve altro per iniziare.

Sul versante scheduling, attenzione a due cose:

  • Sovrapposizione di esecuzioni: se un workflow dura più dell'intervallo dello schedule, rischi di averne due in parallelo. Si mitiga con un lock su tabella o con Split In Batches e una coda.
  • Fuso orario: n8n lavora con cron in timezone configurabile. Se hai negozi in regioni diverse, meglio ancorarsi a UTC e convertire nella query, non nel workflow.

Infine l'osservabilità: la UI tiene la history delle esecuzioni (per default, qualche migliaio), ma per analisi più serie conviene esportare i log su un database separato. Sapere quante volte al giorno un workflow fallisce è un KPI come un altro.

Quando n8n non è la risposta giusta

Tre casi in cui non lo userei:

  • Pipeline dati complesse con dipendenze tra DAG. Se devi fare backfill su 200 tabelle con dipendenze condizionali, Airflow o Dagster sono strumenti fatti per quello.
  • Volumi molto alti e low-latency. n8n è comodo, non è veloce. Se devi processare 10.000 messaggi al secondo, non è la scelta.
  • Logica di business articolata. Se il workflow diventa un algoritmo di 30 nodi con condizioni annidate, stai scrivendo codice in un'interfaccia grafica. A quel punto scrivi codice.

n8n brilla quando i volumi sono modesti, la logica è da 5 a 25 nodi, i dati sono sensibili e vuoi vedere cosa succede senza aprire un terminale.

Conclusione: cosa portarsi a casa

Tre punti che riassumono la mia esperienza con n8n self-hosted:

  • Il self-hosting ha senso quando i dati e i volumi diventano reali. Se stai collegando un database aziendale, un LLM interno o un gestionale, tenere tutto sulla tua infrastruttura semplifica compliance e costi.
  • Il modello "lista di item" è la chiave. Capito quello, i nodi di merge, split e code diventano comprensibili e tutto il resto va a posto.
  • La differenza tra un prototipo e qualcosa che gira davvero sta nel trattamento degli errori. Retry, Error Workflow, avvisi mirati, controllo della sovrapposizione: sono le parti meno divertenti e più utili.

Se stai iniziando, il mio consiglio è partire da un workflow piccolo e noioso — una sync ogni ora, un alert quotidiano — e farlo girare per due settimane prima di aggiungerne un altro. La tentazione è disegnare subito la mappa di tutte le automazioni aziendali. Quasi sempre finisce con dieci workflow rotti che nessuno guarda.


Foto di copertina di Taylor Vick su Unsplash.