SSD Nodes Learn 🎉 VPS da $5.50/mese
Guide Matt ConnorDi Matt Connor · Aggiornato 2026-08-13

Self-hosting di Superlog: requisiti e installazione

Scopri cosa installa davvero Superlog: Postgres, ClickHouse, collector OTLP e quattro servizi Node, con Docker Compose e una stima realistica delle risorse.

Cosa installa realmente Superlog in self-hosting

Per eseguire Superlog in self-hosting, cloni il repository, avvii Postgres, ClickHouse e un collector OpenTelemetry con Docker Compose, esegui una migrazione del database e quindi avvii dal codice sorgente quattro servizi Node. Le applicazioni inviano trace, log e metriche OTLP (protocollo OpenTelemetry) a una porta di raccolta. Superlog calcola l'impronta degli eventi, raggruppa quelli ripetuti in un singolo incidente e un agent produce una prima analisi di triage. L'installazione richiede un pomeriggio. Prima di iniziare, è importante valutare l'occupazione di risorse e i limiti effettivi.

Superlog è distribuito con licenza Apache 2.0 e si trova all'indirizzo github.com/superloglabs/superlog. Ad agosto 2026 conta circa 1.2k stelle, all'incirca 460 commit su main e nessun release tag. Questo aspetto determina la procedura di installazione: git checkout v1.0.0 non contiene nulla da estrarre, quindi devi fissare autonomamente un commit oppure eseguire la versione di main presente al momento della clonazione.

Cosa risponde Superlog che Uptime Kuma e Langfuse non rispondono

Gli strumenti di monitoraggio self-hosted possono sembrare equivalenti dall'esterno. Non lo sono, e scegliere quello sbagliato consuma risorse del server senza offrire alcun vantaggio.

Superlog risponde a una domanda diversa: qualcosa si è guastato, che cosa si è guastato e perché. Non gestisce le chiamate LLM e non esegue verifiche dall'esterno. Acquisisce dati OTLP dal normale codice applicativo e inserisce un agente nella fase di triage, cioè nella prima analisi che eseguirebbe comunque una persona reperibile.

Per il budget di un VPS, la differenza importante riguarda lo storage. Uptime Kuma funziona senza problemi con 1 GB di RAM perché memorizza alcune migliaia di risultati dei controlli. Superlog utilizza un column store, perché la telemetria viene scritta una volta e poi interrogata per intervalli temporali su milioni di righe. Questo è il motivo per cui serve ClickHouse e non Postgres. Postgres resta comunque nello stack e contiene i pochi dati relazionali: progetti, utenti, incidenti e chiavi di ingestione.

Che cosa avvia effettivamente docker compose up -d?

Tre container, nessuno dei quali è Superlog. Questo sorprende chi si aspetta un'installazione con un solo comando.

  • postgres:16, pubblicato sulla porta host 5434
  • clickhouse/clickhouse-server:26.1, sulla porta 8123 per HTTP e 9000 per il protocollo nativo
  • otel/opentelemetry-collector-contrib:0.150.1, sulla porta 4317 per gRPC e 4318 per OTLP su HTTP

Le applicazioni Superlog vengono eseguite sull'host, a partire dal codice sorgente, e avviate da pnpm dev. Ad agosto 2026, nel repository non è presente alcun file Compose per la produzione. Per un'installazione permanente servono quindi unità systemd proprie per ciascuna applicazione, basate sul relativo script start, oppure i Dockerfile delle singole applicazioni presenti nell'albero del repository.

Tieni presente il percorso seguito da uno span, perché ogni errore descritto di seguito interrompe uno dei suoi passaggi. L'applicazione invia i dati OTLP al proxy di acquisizione di Superlog. Il proxy autentica la richiesta con la chiave di ingestione, vi applica l'ID del progetto e la inoltra al collector. Il collector rimuove tutti gli attributi superlog.* che il client ha tentato di impostare, aggiunge superlog.project_id dall'header fornito dal proxy, raggruppa i dati e li scrive in ClickHouse. L'applicazione web e l'API leggono quindi la telemetria da ClickHouse e tutti gli altri dati da Postgres.

La rimozione di questi attributi è un vero controllo per il multi-tenancy, non un elemento decorativo. Senza di essa, chiunque disponga di una chiave di ingestione valida potrebbe impostare autonomamente superlog.project_id e scrivere nei dati di un altro progetto.

Quanto deve essere grande il VPS?

Per una singola installazione a nodo con un volume di ingestione ridotto, prevedi 4 vCPU, 8 GB di RAM e 40 GB di SSD. È una dimensione minima di pianificazione, non una misurazione. Usala come punto di partenza e verificala in base al tuo traffico.

La memoria viene utilizzata in quattro aree. ClickHouse è progettato per macchine con molta RAM e le sue impostazioni predefinite lo riflettono. In questo caso Postgres 16 ha un consumo contenuto, perché gestisce i metadati e non i dati di telemetria. Anche il collector ha un consumo contenuto. I quattro processi Node, invece, non sono altrettanto leggeri: un server di sviluppo Vite più tre processi tsx watch utilizzano ciascuno centinaia di megabyte. Per questo pnpm dev su una macchina con 2 GB è problematico.

Il disco è il problema meno evidente. pnpm install in questo monorepo scarica AWS SDK, un client ClickHouse, OpenTelemetry SDK e una toolchain React prima ancora di acquisire un singolo span. Successivamente ClickHouse cresce in base al traffico. Misura entrambi:

df -h /
free -m
docker stats --no-stream
docker compose exec clickhouse clickhouse-client --database superlog --query "SELECT table, formatReadableSize(sum(bytes_on_disk)) AS size FROM system.parts WHERE active AND database = 'superlog' GROUP BY table ORDER BY sum(bytes_on_disk) DESC"

Con un volume ridotto, cioè pochi servizi che inviano alcune centinaia di span al minuto, il server resta inattivo e ClickHouse utilizza poche risorse per la maggior parte del tempo. Il carico problematico è il picco: un deploy errato può produrre migliaia di errori identici al minuto. Il fingerprinting li raggruppa in un singolo incidente per chi legge, ma ClickHouse continua a scrivere ogni riga sottostante.

La conservazione dei dati è configurabile. L'exporter ClickHouse del collector crea le tabelle, otel_traces, otel_logs e una tabella per ogni tipo di metrica. Applica una durata TTL solo se la configurazione in infra/collector/config.yaml ne imposta una. Nulla scade automaticamente. Un mese di traffico intenso può quindi riempire l'intero disco se non lo pianifichi.

Installazione da un commit bloccato

git clone https://github.com/superloglabs/superlog.git
cd superlog
git tag -l
git log -1 --format='%H %cs %s'

git tag -l non deve stampare nulla; questo è il risultato previsto ad agosto 2026. Scegli il commit che hai verificato e mantieniti su quello:

git checkout 0d3a6c8bb63eda3493e6ba0003e7c2a70750bc1e

Passiamo alla toolchain:

node -v
corepack enable
corepack prepare pnpm@9.12.0 --activate
pnpm -v

package.json dichiara engines.node come >=20.0.0 e packageManager come pnpm@9.12.0. Se esegui l'installazione con una versione precedente di Node, pnpm si interrompe con ERR_PNPM_UNSUPPORTED_ENGINE e indica la versione richiesta. Il pacchetto nodejs nell'archivio di Ubuntu 24.04 è precedente alla versione 20. Installa quindi Node 20 o una versione successiva da NodeSource oppure tramite nvm. Il repository include un .nvmrc, quindi nvm use seleziona la versione prevista se hai nvm.

pnpm install
docker compose up -d
docker compose ps

Attendi i controlli di integrità invece di interpretare up -d come indicazione che il servizio è pronto. Sia Postgres sia ClickHouse ne dichiarano uno nel file compose:

curl -sS http://127.0.0.1:8123/ping
pg_isready -h 127.0.0.1 -p 5434 -U postgres

ClickHouse risponde su Ok. e pg_isready risponde su accepting connections. Un rifiuto della connessione sulla porta 8123 indica che il container è ancora in avvio oppure si è arrestato. docker compose logs clickhouse mostra quale delle due condizioni si è verificata e docker inspect $(docker compose ps -q clickhouse) | grep -i oomkilled segnala true quando il kernel lo ha terminato per mancanza di memoria. Questo indica che il server è sottodimensionato, non che la configurazione sia errata.

Passiamo quindi alla migrazione e alle applicazioni:

pnpm --filter @superlog/db db:migrate
pnpm dev

Nota la porta: 5434, non 5432. Il file compose pubblica Postgres sulla porta 5434 per evitare conflitti con un'istanza di Postgres già installata sull'host. Anche i file .env.example dell'applicazione corrispondono, con DATABASE_URL=postgres://postgres:postgres@localhost:5434/superlog. Se punti la migrazione alla porta 5432 su un server che esegue già Postgres, ottieni un rifiuto della connessione oppure, peggio, applichi la migrazione al database sbagliato.

pnpm dev avvia i quattro processi elencati nel Procfile del repository: api, web, worker e proxy. Ciascun processo reindirizza una copia dell'output in tmp/logs/, quindi tail -f tmp/logs/proxy.log è il file da monitorare per l'ingestione. Il README indica l'applicazione web su http://localhost:5173, l'API su http://localhost:4100 e l'endpoint di ingestione OTLP su http://localhost:4101.

Verifica quale processo è effettivamente in ascolto prima di configurare i client:

ss -lntp | grep -E '4100|4101|5173'
curl -sS http://127.0.0.1:4101/health

Questo aspetto sarà importante in seguito. Il proxy legge la propria porta dalla variabile d'ambiente PORT e usa 4000 se PORT non è impostata. Lo stack di sviluppo imposta la variabile automaticamente. Un'unità systemd che scrivi manualmente non lo fa. Di conseguenza, un exporter indirizzato alla porta 4101 mentre il proxy è in ascolto sulla porta 4000 fallisce con un rifiuto della connessione senza fornire altre indicazioni.

Invia una traccia, genera un errore, visualizza un incidente

Crea un progetto nell'applicazione web e copia la relativa ingest key. Il servizio di ingest autentica ogni richiesta tramite questa chiave. La telemetria inviata senza chiave non raggiunge mai ClickHouse.

Configura un SDK OpenTelemetry affinché punti al servizio di ingest tramite le variabili d'ambiente standard:

export OTEL_SERVICE_NAME=checkout-api
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4101
export OTEL_EXPORTER_OTLP_HEADERS='x-api-key=YOUR_INGEST_KEY'

Il servizio di ingest legge la chiave dall'header x-api-key. Accetta anche authorization: bearer YOUR_INGEST_KEY se l'exporter è più semplice da configurare in questo modo. Espone i tre percorsi OTLP standard, /v1/traces, /v1/logs e /v1/metrics, oltre a /health.

È importante chiarire un comportamento. OTEL_EXPORTER_OTLP_ENDPOINT è un URL di base e l'SDK aggiunge a questo URL il percorso del segnale. Le variabili specifiche del segnale, come OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, vengono usate esattamente come sono scritte, senza aggiungere alcun percorso. Se imposti la variabile specifica del segnale su http://127.0.0.1:4101, ogni export viene inviato a /. Questo non è un percorso valido. Di conseguenza, nulla arriva al servizio di ingest e l'SDK registra un errore di export, mentre l'applicazione sembra funzionare correttamente.

Per un servizio Node, il percorso senza modifiche al codice è sufficiente per verificare la pipeline:

npm install @opentelemetry/api @opentelemetry/auto-instrumentations-node
node --require @opentelemetry/auto-instrumentations-node/register server.js

Ora interrompi intenzionalmente qualcosa. È sufficiente una route che generi un errore:

curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/boom

Controlla i passaggi nell'ordine seguente. Il primo punto in cui il conteggio si interrompe indica il componente guasto:

tail -n 50 tmp/logs/proxy.log
docker compose exec clickhouse clickhouse-client --database superlog --query 'SELECT count() FROM otel_traces'

Un conteggio in aumento in otel_traces con l'applicazione web vuota indica una mancata corrispondenza del progetto. Controlla a quale progetto appartiene la ingest key. Un conteggio invariato, insieme ad attività nel log del proxy, indica un problema nel collector o nella scrittura su ClickHouse. In questo caso, leggi docker compose logs collector. L'assenza totale di attività nel log del proxy indica che l'exporter non ha raggiunto il servizio di ingest: la porta o il percorso potrebbero essere errati oppure la chiave potrebbe essere stata rifiutata.

Nell'applicazione web, questi errori ripetuti vengono visualizzati come un unico incidente, non come una riga per ogni richiesta. Superlog calcola l'impronta dei segnali in ingresso e raggruppa quelli corrispondenti. In questo modo, la casella di posta contiene un solo elemento invece di 4,000 errori identici. L'agent scrive quindi l'analisi sopra questo gruppo.

Il passaggio di analisi chiama un modello. Per questo motivo, il worker deve avere un provider del modello configurato. Ricava i nomi delle variabili dal file .env.example presente nella directory di ogni applicazione del commit fissato, invece di usare documentazione esterna. Questi nomi cambiano insieme a main. Lo stesso vale per le integrazioni GitHub e Sentry, che includono la propria documentazione di configurazione in docs/github-app-setup.md e docs/sentry-app-setup.md. La documentazione dei webhook payload si trova in docs/webhooks.md.

Mantieni l’endpoint di ingestione privato e l’agent in sola lettura

Docker pubblica le porte dei container su 0.0.0.0 per impostazione predefinita. Queste porte pubblicate ignorano ufw, perché Docker scrive le proprie regole nella catena DOCKER-USER, che viene valutata prima che ufw elabori il pacchetto. Su un VPS con un indirizzo IP pubblico, il file compose distribuito espone ClickHouse HTTP sulla porta 8123 e Postgres sulla porta 5434, rendendoli raggiungibili da Internet. Le credenziali presenti nel file sono valori predefiniti per lo sviluppo: l’utente ClickHouse default con password vuota e Postgres con postgres come utente e password.

Associane il binding all’interfaccia loopback. Nel file compose, ogni porta pubblicata ricava il lato host da una variabile d’ambiente. È quindi sufficiente creare un file .env nella directory radice del repository:

POSTGRES_HOST_PORT=127.0.0.1:5434
CLICKHOUSE_HTTP_HOST_PORT=127.0.0.1:8123
CLICKHOUSE_TCP_HOST_PORT=127.0.0.1:9000
COLLECTOR_GRPC_HOST_PORT=127.0.0.1:4317
COLLECTOR_HTTP_HOST_PORT=127.0.0.1:4318

Verifica il risultato prima di considerarlo corretto, quindi ricrea i container:

docker compose config
docker compose up -d
ss -lntp | grep -E '5434|8123|9000|4317|4318'

docker compose config stampa il file con i valori risolti, così puoi leggere 127.0.0.1:5434:5432 invece di procedere per supposizioni. A quel punto ss dovrebbe mostrare 127.0.0.1:5434 e non dovrebbe mai mostrare 0.0.0.0:5434. Non cercare di correggere il problema con un file di override compose che ridefinisce ports. Compose concatena infatti gli elenchi delle porte tra i diversi file, invece di sostituirli. Il risultato sarebbe la presenza di entrambi i binding, con la porta pubblica ancora esposta.

Anche l’endpoint di ingestione richiede la stessa attenzione. La chiave di ingestione viene trasmessa in un header, quindi deve essere protetta da TLS (transport layer security). Termina TLS in nginx o Caddy davanti al proxy oppure mantieni l’ingestione all’interno di una rete privata o di un tunnel WireGuard. L’applicazione web sulla porta 5173 è un server di sviluppo Vite e non deve essere esposta a Internet.

Passiamo all’agent. Superlog presenta l’agent come uno strumento che analizza gli incidenti e propone una correzione. La parola importante è «propone». Mantienilo in sola lettura rispetto alla produzione finché non ne avrai osservato il comportamento su alcuni incidenti reali. Concedi alla GitHub App scope di lettura e permettile di aprire pull request da sottoporre alla tua revisione. Un agent che legge la telemetria e scrive una patch è utile. Un agent che può riavviare i servizi comporta un livello di rischio diverso. Questa deve essere una decisione consapevole, non un’impostazione predefinita ereditata senza verifica. Anche i costi richiedono la stessa attenzione, perché ogni analisi comporta una chiamata al modello: definisci il budget per la spesa dell’agent su un VPS prima di indirizzarlo verso un sistema di produzione rumoroso e conserva un registro delle attività effettivamente eseguite dall’agent, così ogni pull request inattesa dispone di una traccia di audit.

Errori comuni e stringhe che li identificano

  • ERR_PNPM_UNSUPPORTED_ENGINE durante pnpm install indica che Node è precedente alla versione 20. node -v lo conferma su una sola riga.
  • ECONNREFUSED 127.0.0.1:5434 durante la migrazione indica che lo stack compose non è attivo oppure che DATABASE_URL specifica la porta errata.
  • Il riavvio continuo di ClickHouse è solitamente dovuto alla memoria. Leggere docker compose logs clickhouse, quindi controllare nel container se OOMKilled è impostato su true.
  • Se un exporter segnala il completamento mentre l'applicazione web resta vuota, in genere i dati sono stati inviati direttamente al collector sulla porta 4318. In questo modo viene saltata l'associazione al progetto eseguita dal proxy.
  • Un rifiuto della connessione sulla porta 4101 in un'installazione di produzione indica che il proxy è ricaduto su PORT=4000. Impostare PORT esplicitamente nel file dell'unità.
  • Se docker compose ps mostra 0.0.0.0:8123, i binding sul loopback non sono effettivi. Eseguire docker compose config e leggere le porte risolte.

Flawless, HyperProbe e il ruolo di Superlog

Questa categoria è recente e gli strumenti differiscono per il livello di accesso concesso all’agente. Flawless è uno strumento AI SRE (site reliability engineering) open source rivolto a Kubernetes. Legge i dati da uno stack Prometheus, Loki e Grafana già esistente, invece di gestire direttamente la pipeline. HyperProbe segue l’approccio opposto: è un prodotto in hosting, closed source ad agosto 2026, che inserisce probe in sola lettura in un processo in esecuzione per acquisire lo stato delle variabili ed espone tale stato a un assistente tramite MCP (model context protocol).

Superlog si colloca tra i due. Gestisce l’intera pipeline, dall’ingestione OTLP fino all’archiviazione in ClickHouse, e colloca l’agente nella fase di triage, non in quella di correzione. Per questo il self-hosting è una decisione infrastrutturale, non un container da dimenticare dopo l’avvio. Quando esegui Superlog, gestisci un column store, che richiede la stessa attenzione di qualsiasi altro database sotto la tua responsabilità.

FAQ

Quanta RAM richiede un Superlog self-hosted?

Prevedi 8 GB di RAM, 4 vCPU e 40 GB di disco per un singolo nodo con un volume di ingestione ridotto. Lo stack comprende Postgres, ClickHouse, un collector OpenTelemetry e quattro processi Node; ClickHouse richiede inoltre margine di risorse. Un VPS da 1 GB o 2 GB non è sufficiente: pnpm install da solo è pesante e, sotto carico, il kernel termina ClickHouse tramite l'out-of-memory killer. Misura i tuoi valori con docker stats --no-stream e free -m invece di affidarti a una cifra pubblicata, inclusa questa.

A quale porta devo puntare il mio exporter OTLP?

Al proxy di ingestione di Superlog, che il README configura su http://localhost:4101. Il proxy serve /v1/traces, /v1/logs e /v1/metrics e usa la ingest key del progetto, ricavata dall'header x-api-key o da un header authorization: bearer. La porta 4318 appartiene al collector OpenTelemetry sottostante. Esportare direttamente su quella porta bypassa il proxy, che è il componente che assegna ai dati l'id del progetto. Se PORT non è impostata, il proxy usa la porta 4000. Esegui ss -lntp e verifica a quale porta è associato prima di dare per scontata la porta 4101.

Superlog sostituisce Uptime Kuma o Zabbix?

No. Uptime Kuma verifica da una rete esterna se un endpoint risponde. Zabbix monitora le metriche di host e servizi in base alle soglie configurate. Superlog acquisisce traces, log e metriche emessi dalle applicazioni e raggruppa i guasti ricorrenti in incidenti. Mantieni anche un monitoraggio uptime esterno, perché un probe eseguito altrove continua a segnalare il problema quando a smettere di funzionare è il server che ospita la pipeline di telemetria.

L'agent Superlog può modificare i miei sistemi di produzione?

Solo tramite le autorizzazioni che gli concedi. Il suo output consiste in un'indagine e in una modifica proposta, che deve essere verificata da una persona. Inizia mantenendo la GitHub App con autorizzazioni di sola lettura e pull request. Limita inoltre alla lettura le credenziali eventualmente disponibili al worker. Considera l'accesso in scrittura alla produzione una decisione separata e intenzionale: un agent che può riavviare i servizi richiede un livello di fiducia molto maggiore rispetto a un agent che legge la telemetria e prepara una patch da sottoporre a revisione.

Devo fissare un commit o seguire main?

Fissa un commit. Ad agosto 2026 il repository non contiene release tag, quindi main è l'unico riferimento mobile disponibile e riceve diversi commit ogni settimana. Registra lo SHA che hai testato e distribuisci quello. Prima di passare a un commit successivo, esamina il diff. git log --oneline <old-sha>..main contiene la revisione. I file .env.example specifici delle singole applicazioni sono il primo punto da controllare per individuare le variabili richieste di recente dopo ogni aggiornamento.