Vai al contenuto

Self-hosting di ARBR (control plane) con Docker Compose

Installa ARBR, il control plane LLM open-source per ottimizzare costi e routing, con Docker Compose: demo mode in un comando e overlay production.

Self-hosting di ARBR (control plane) con Docker Compose

Testato il: 2026-09-04 Ambiente: Docker Engine 24+ · Docker Compose v2.24.4 (minimo richiesto dal repo) · mongo:7 (immagine del compose) · Node.js >= 18

Prerequisiti

  • Un host con Docker Engine e Docker Compose v2.24.4 o più recente. Il repo dichiara questo minimo in DEPLOYMENT.md: il profilo production usa la sintassi !override, che richiede il motore Compose recente.
  • git per clonare il repo.
  • Nessuna API key: la demo semina dati realistici e funziona senza credenziali.
  • Per i passi production ti serve solo node sulla macchina host, per generare le chiavi. Se non ce l'hai, qualsiasi generatore di hex a 32 byte va bene.

1. Clonare il repo

Parti dal repo ufficiale e clona il branch main:

git clone https://github.com/project-arbr/arbr-control-plane.git
cd arbr-control-plane

Cosa devi vedere: la cartella arbr-control-plane con dentro docker-compose.yml, .env.example, DEPLOYMENT.md e le cartelle server/ e web/. Se la cartella è vuota o il clone fallisce, il repo non è raggiungibile: non procedere, il resto della guida dipende da questi file.

2. Preparare il file .env

Il repo non richiede configurazione per partire. Copia il template e guarda cosa contiene:

cp .env.example .env

Il file .env.example spiega tutto con commenti: ogni variabile ha un default sicuro, nessuna chiave è obbligatoria per l'avvio. Le tre righe che contano davvero:

PORT=4100
HOST=0.0.0.0
MONGO_URI=mongodb://localhost:27017/arbr-control-plane

PORT e HOST definiscono il bind del server. MONGO_URI nel compose demo viene sovrascritta da mongodb://mongo:27017/arbr-control-plane (il servizio mongo del network compose), quindi quella del .env serve solo se esegui il server fuori da Docker.

Non toccare nulla ora: per la demo lasciamo ARBR_ADMIN_KEY e ARBR_ENCRYPTION_KEY vuote e SEED_ON_BOOT al valore del compose. Al passo 5 le valorizzeremo.

3. Avviare lo stack in modalità demo

Il compose base è un profilo demo/eval: carica MongoDB, compila l'app e semina dati sintetici al boot.

docker compose up

Ecco cosa ti aspetti di vedere:

  1. Docker scarica mongo:7 e compila l'immagine dell'app dal Dockerfile locale (la prima volta richiede qualche minuto).
  2. Il servizio mongo passa l'healthcheck (mongosh ping, ogni 10 secondi) prima che app parta, grazie al depends_on con condition: service_healthy.
  3. Al boot l'app semina i dati demo e sincronizza il catalogo modelli da LiteLLM, se il registry è vuoto.

Quando il log mostra il server in ascolto, apri la dashboard su localhost:4100 nel browser. Il boot log stampa porta, modalità (demo/live) e se l'admin auth è attiva.

docker compose up resta in foreground: tieni il terminale aperto per seguire il boot e ferma tutto con Ctrl+C quando vuoi.

4. Verificare il gateway

La dashboard demo funziona senza chiavi. Per vedere l'intero ciclo di ottimizzazione segui il percorso del README: Overview per costi e modelli, Recommendations → Recompute per far emergere un'opportunità, e apri la raccomandazione seedata "classification on gpt-4o", già approvata con un canary attivo.

Due comandi utili dentro il container (verificano che la demo sia viva):

docker compose exec app npm run demo:seed
docker compose exec app npm run demo:reset

demo:seed semina un secondo canary che sta violando i suoi guardrail: puoi rollbackarlo dal dashboard o aspettare che l'auto-rollback lo fermi da solo. demo:reset rimuove solo i dati seedati, mai i dati reali.

L'endpoint di liveness è pubblico e non richiede autenticazione:

curl -s localhost:4100/health

Risposta attesa, un JSON con "ok":true. Se risponde, il gateway e la dashboard sono su.

5. Overlay production (opzionale ma consigliato)

La modalità demo semina dati a ogni boot e azzera i request record: SEED_ON_BOOT=true è scritto nel compose demo con un avviso esplicito. Mai esporre un'istanza così, oltre a un localhost.

Il seeding è distruttivo — Con `SEED_ON_BOOT=true` ogni riavvio del container azzera i request record prima di riseminare i dati demo. In produzione è disabilitato dall'overlay: mai lanciare il compose base con dati reali dentro.

Il repo fornisce un overlay production, docker-compose.prod.yml, che forza NODE_ENV=production, disabilita il seeding, lega la porta 4100 al loopback e rifiuta di partire senza due chiavi. Generale eseguendo due volte il comando che il DEPLOYMENT.md documenta:

node -e "console.log('admin:', require('crypto').randomBytes(32).toString('hex'))"
node -e "console.log('admin:', require('crypto').randomBytes(32).toString('hex'))"

Poi apri .env e imposta le tre variabili che il DEPLOYMENT.md marca come obbligatorie:

ARBR_ADMIN_KEY=<la prima chiave generata>
ARBR_ENCRYPTION_KEY=<la seconda chiave generata>
SEED_ON_BOOT=false

ARBR_ADMIN_KEY chiude la dashboard e l'admin API. ARBR_ENCRYPTION_KEY cifra a riposo le chiavi provider salvate dalla dashboard. SEED_ON_BOOT=false è l'unica protezione contro l'azzeramento dei dati.

Avvia con i due file insieme:

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Il profilo production usa ports: !override per rimuovere il bind pubblico 0.0.0.0:4100 e sostituirlo con 127.0.0.1:4100:4100: la porta è raggiungibile solo da un reverse proxy sulla stessa macchina. Il DEPLOYMENT.md consiglia nginx o un ALB davanti, con TLS in terminazione e proxy_read_timeout 300s (le chiamate LLM sono lente).

Il compose demo espone la porta — Il bind `0.0.0.0:4100` del compose base rende dashboard e gateway raggiungibili da tutta la rete. Se non metti un reverse proxy davanti, chiunque può arrivare alla dashboard aperta. In produzione usa sempre l'overlay, mai il compose base da solo.

Con SEED_ON_BOOT=false la dashboard parte vuota, senza dati demo. È corretto: il catalogo modelli viene comunque sincronizzato da LiteLLM al primo boot.

6. Operazioni di routine

Log del server:

docker compose logs -f app

Upgrade del repo, la sequenza ufficiale del DEPLOYMENT.md:

git pull && docker compose build app && docker compose up -d app

Lo stato durevole sta tutto in MongoDB: un restart dell'app perde solo le cache in memoria.

Backup e restore (il volume arbr_mongo_data è l'unica cosa che contiene dati tuoi):

bash ops/backup.sh
bash ops/restore.sh <file>
restore.sh è distruttivo — Ripristina il database dal backup, chiede conferma e riavvia lo stack. Esegui il backup su un cron prima di pensare al restore: senza un archivio recente non c'è nulla da ripristinare.

Verifica

A lavoro finito, in ordine:

  1. docker compose ps mostra mongo con stato Up (e healthy quando l'healthcheck passa) e app con stato Up.
  2. curl -s localhost:4100/health risponde con {"ok":true,...}.
  3. In demo: la dashboard su localhost:4100 mostra i dati seedati e Recommendations contiene opportunità calcolate su traffico sintetico.
  4. In production: la dashboard chiede login con ARBR_ADMIN_KEY, la porta 4100 è in ascolto solo su loopback e il boot log stampa la modalità live con l'admin auth attiva (niente warning "admin aperta", che compare solo con la chiave vuota).

Se il gateway risponde e la dashboard carica, il self-hosting è completo: da qui aggiungi una chiave provider dalla pagina Models (o via .env, che ha precedenza) e punta le tue applicazioni a POST /v1/chat o POST /v1/chat/completions.

Limiti noti

  • Non testato in prima persona: durante la stesura non avevo un host Docker disponibile, quindi la guida documenta i comandi e i file ufficiali del repo (main branch, verificati il 2026-09-04) senza un'esecuzione empirica. Versioni e comportamenti descritti sono quelli dichiarati da README, DEPLOYMENT.md, docker-compose.yml, .env.example e docker-compose.prod.yml.
  • La demo semina dati a ogni boot e azzera i request record: se lasci SEED_ON_BOOT=true e riavvii, perdi lo storico delle chiamate demo. In production è disabilitato dall'overlay, ma se usi solo il compose base ricordalo.
  • Il bind 0.0.0.0:4100 del compose demo espone dashboard e gateway sulla rete: in produzione usa sempre l'overlay (loopback + reverse proxy), mai il compose base da solo.
  • Il caching di risposta, i rate limit per chiave e le cache di regole sono in-process: due repliche dietro un load balancer non condividono questi contatori. Per una sola istanza non è un problema, ed è il modello di deployment che il repo raccomanda.
Condividi