Files
ThothII/docs/installazione-docker-4-contesti.md
T

16 KiB

Installazione Docker nei quattro contesti operativi

Questa guida descrive l'installazione di ThothII usando le due immagini applicative:

  • thothii-core: backend Fastify, harness tht e Pi;
  • thothii-frontend: frontend React servito da nginx.

I database e i servizi di embedding restano esterni, salvo il profilo opzionale local-vector, che avvia un PostgreSQL/pgvector nello stesso progetto Compose.

Prerequisiti comuni

Installare Docker Engine/Compose v2 sul server oppure Docker Desktop su macOS/Windows. La macchina deve poter raggiungere:

  • il DWH/DWH REST, se usato dal workspace;
  • il vector DB REST o pgvector;
  • il servizio di embedding (Ollama o endpoint compatibile);
  • il provider del modello Pi, se si usano provider hosted.

Clonare il repository e lavorare dalla sua radice:

git clone <URL-REPOSITORY> ThothII
cd ThothII
cp deploy/env.example deploy/.env       # solo per sviluppo locale

I secret non devono essere inseriti in deploy/.env, nei file workspace o negli URL. deploy/.env serve solo a valori di configurazione non riservati (host, porte, nomi di database): Compose può mostrarne i valori durante config, nei log o nella diagnostica. Un workspace YAML deve contenere al massimo un riferimento come password_file, mai la password stessa; gli URL non devono contenere user, password o token.

Salvare invece ogni credenziale in un file separato fuori dal repository. Sul sistema host il file deve essere leggibile solo dall'utente/servizio che esegue Docker (0400 se solo lettura, 0600 se l'operatore deve poterlo aggiornare). Compose lo monta poi nel container come secret read-only sotto /run/secrets. Il 0444 osservabile dentro il container è normale per il mount dei secret Docker e non rende il file host pubblico: il file host resta protetto e il container riceve una copia/mount temporaneo non scrivibile.

Il modello Pi usa THT_MODEL_API_KEY_SECRET_FILE per i provider autenticati con una singola chiave. Provider composti (Bedrock, Azure OpenAI Responses, Cloudflare Workers AI/Gateway) sono rifiutati esplicitamente: richiedono un bundle di credenziali non rappresentabile da un solo file.

1. Server applicativo insieme a DWH e vector DB

Questo profilo è adatto quando ThothII, il database relazionale e il vector DB sono nella stessa rete/server, ma i database non devono necessariamente essere containerizzati da ThothII. Si usa il profilo external; gli endpoint possono essere nomi DNS, IP privati o nomi di servizio della rete Docker.

Configurazione

Creare i file secret fuori dal repository. Su Linux/macOS:

sudo install -d -m 700 /etc/thothii
sudo install -m 600 /dev/null /etc/thothii/dwh-api-key
sudo install -m 600 /dev/null /etc/thothii/vector-reader-api-key
sudo install -m 600 /dev/null /etc/thothii/vector-writer-api-key
sudo install -m 600 /dev/null /etc/thothii/model-api-key
sudo install -m 600 /dev/null /etc/thothii/ca-chain.pem

# Scrivere il valore senza mostrarlo nella shell history:
sudo sh -c 'umask 077; printf "%s" "$(cat)" > /etc/thothii/dwh-api-key' \
  < /percorso/protetto/dwh-api-key

install è un comando Unix per creare/copiare un file impostando contestualmente i permessi. In install -m 600 /dev/null DEST:

  • /dev/null è una sorgente vuota, quindi il comando crea (o sostituisce) DEST senza inserire una password;
  • -m 600 imposta i permessi rw------- (lettura/scrittura solo per il proprietario);
  • DEST è il file che l'operatore deve poi riempire con il secret.

Il percorso /etc/thothii è solo una convenzione dell'esempio per un server Linux: il software non cerca automaticamente le API key in /etc. Il percorso host è quello indicato nelle variabili THT_*_SECRET_FILE; Compose legge quel file e lo monta nel container al percorso interno dichiarato dal servizio, normalmente /run/secrets/dwh_api_key, /run/secrets/vector_reader_api_key o /run/secrets/model_api_key. Si può usare, ad esempio, /srv/thothii/secrets, /opt/company/secrets o un secret manager che materializzi i file, senza cambiare il codice: va cambiata solo la variabile THT_*_SECRET_FILE.

Il comando non è un gestore di password e non va usato per stampare il secret sulla riga di comando. Su Windows è preferibile usare WSL2 per creare il file con permessi Unix, oppure creare un file locale ACL-protetto tramite uno strumento aziendale di gestione dei secret. Non usare ConvertFrom-SecureString come contenuto del file: produce una rappresentazione cifrata che ThothII non può usare come API key.

# Dentro WSL2; il path /mnt/c/... deve essere condiviso con Docker Desktop.
mkdir -p /mnt/c/Users/<utente>/.thothii/secrets
umask 077
read -r -s secret; printf '%s' "$secret" > /mnt/c/Users/<utente>/.thothii/secrets/dwh-api-key
unset secret

Per i secret usati da Docker Desktop è preferibile una directory locale non sincronizzata e accessibile a Docker Desktop; non usare una cartella Git o OneDrive condivisa. In alternativa, creare i file dentro WSL2 con umask 077 e passare a Compose il path Windows risultante.

Impostare gli endpoint e i riferimenti ai secret nel servizio core (preferibilmente tramite un file .env gestito dall'operatore, non committato):

export THT_DB_NAME=warehouse
export THT_DWH_REST_URL=https://dwh.internal.example
export THT_VEC_REST_URL=https://vectors.internal.example
export THT_OLLAMA_URL=https://embeddings.internal.example
export THT_DWH_API_KEY_SECRET_FILE=/etc/thothii/dwh-api-key
export THT_VEC_API_KEY_SECRET_FILE=/etc/thothii/vector-reader-api-key
export THT_VEC_WRITE_API_KEY_SECRET_FILE=/etc/thothii/vector-writer-api-key
export THT_MODEL_API_KEY_SECRET_FILE=/etc/thothii/model-api-key
export THT_CA_SECRET_FILE=/etc/thothii/ca-chain.pem
export AUTH_MODE=none
export THOTH_PUBLIC_EXPOSURE=false

Queste variabili con suffisso _SECRET_FILE sono input di Compose sul server host. Non vanno confuse con le variabili _FILE viste dal processo dentro il container: ad esempio THT_MODEL_API_KEY_SECRET_FILE=/etc/thothii/model-api-key viene trasformata dal file deploy/compose.production.yaml in THT_MODEL_API_KEY_FILE=/run/secrets/model_api_key. Il backend legge quindi /run/secrets/model_api_key, non /etc/thothii/model-api-key.

Preparare un file YAML in deploy/workspaces/. Il workspace è la configurazione logica di una installazione: seleziona gli adapter, gli endpoint non riservati e le radici persistenti. Per esempio, con DWH REST e vector DB HTTP:

language: en
dwh:
  type: thoth_rest
  database: {database: warehouse, schema: datawarehouse}
  endpoint: {base_url: https://dwh.internal.example}
vectors:
  type: thoth_vector_http
  reader: {base_url: https://vectors.internal.example}
  writer: {base_url: https://vectors.internal.example}
roots: {artifacts: artifacts, indexes: indexes, sessions: sessions}
evidence: {source_root: /data/source, evidence_dir: evidence}
embeddings: {base_url: https://embeddings.internal.example, model: nomodel, dim: 768}

Con DWH PostgreSQL e pgvector raggiungibili direttamente dalla rete Docker:

language: en
dwh:
  type: postgres_direct
  connection: {host: dwh.internal.example, database: warehouse, schema: public,
               user: thoth_reader, password_file: /run/secrets/dwh_password}
vectors:
  type: pgvector_direct
  reader: {host: vector.internal.example, database: thoth, schema: vectors,
           user: thoth_vector_reader, password_file: /run/secrets/vector_reader_password}
  writer: {host: vector.internal.example, database: thoth, schema: vectors,
           user: thoth_vector_writer, password_file: /run/secrets/vector_writer_password}
roots: {artifacts: artifacts, indexes: indexes, sessions: sessions}

I nomi dei type sono contratti applicativi, non descrizioni libere: usare quelli esposti da tht doctor e dagli esempi del repository (thoth_rest, thoth_vector_http, postgres_direct, pgvector_direct). dwh.type sceglie come interrogare il DWH; vectors.type sceglie come leggere/scrivere il vector DB. Cambiare questi valori può richiedere anche campi specifici dell'adapter e secret file coerenti.

roots contiene percorsi logici, non percorsi host arbitrari. Con THT_DATA_ROOT=/data, artifacts: artifacts diventa /data/workspaces/<workspace>/artifacts (e analogamente per indexes e sessions), evitando che un YAML possa scrivere fuori dal volume applicativo. Un path host va esposto esplicitamente con un bind mount read-only/read-write nel Compose e poi referenziato dal workspace secondo le regole di sicurezza; non inserire /Users/... o C:\\... direttamente in un workspace destinato a più sistemi operativi.

Avvio e verifica

docker compose -f compose.yaml -f deploy/compose.production.yaml \
  --profile external up --build --wait

docker compose -f compose.yaml -f deploy/compose.production.yaml \
  --profile external exec core /opt/venv/bin/tht doctor --json
./scripts/docker-smoke.sh

Il frontend è pubblicato su 127.0.0.1:8080 per default. Per esposizione pubblica usare un reverse proxy autenticato TLS; non impostare THOTH_PUBLIC_EXPOSURE=true senza AUTH_MODE=upstream e senza il proxy che inietta X-Authenticated-User.

2. Mac locale con DWH esterno e vector DB locale

Questo è il profilo consigliato per un Mac Apple Silicon o Intel: Docker Desktop ospita pgvector e ThothII, mentre DWH ed embeddings possono essere remoti. Ollama eseguito sul Mac è raggiungibile dai container con host.docker.internal.

Creare quattro password locali, fuori Git:

mkdir -p ~/.thothii/secrets
for name in bootstrap migrator reader writer; do
  umask 077; openssl rand -base64 32 >"$HOME/.thothii/secrets/$name"
done
export THT_VECTOR_BOOTSTRAP_PASSWORD_SECRET_FILE="$HOME/.thothii/secrets/bootstrap"
export THT_VECTOR_MIGRATOR_PASSWORD_SECRET_FILE="$HOME/.thothii/secrets/migrator"
export THT_VECTOR_READER_PASSWORD_SECRET_FILE="$HOME/.thothii/secrets/reader"
export THT_VECTOR_WRITER_PASSWORD_SECRET_FILE="$HOME/.thothii/secrets/writer"
export THT_OLLAMA_URL=http://host.docker.internal:11434

Avviare il profilo:

docker compose -f compose.yaml -f deploy/compose.local-vector.yaml \
  --profile local-vector up --build --wait

Per eseguire i job di preprocessing usare anche l'overlay che abilita la catena health-check → reconcile → migrate:

docker compose -f compose.yaml -f deploy/compose.local-vector.yaml \
  -f deploy/compose.preprocess.yaml -f deploy/compose.preprocess-local-vector.yaml \
  --profile local-vector --profile preprocess build preprocess-evidence
docker compose -f compose.yaml -f deploy/compose.local-vector.yaml \
  -f deploy/compose.preprocess.yaml -f deploy/compose.preprocess-local-vector.yaml \
  --profile local-vector --profile preprocess run --rm preprocess-evidence

Montare i testi Evidence in /data/source/evidence tramite il workspace o un override Compose. Il volume thoth_data contiene sessioni, artefatti e corpus; vector_data contiene solo pgvector. Per verificare rotazione credenziali e recovery:

./scripts/local-vector-smoke.sh
./scripts/local-vector-smoke.sh --backup-restore

3. PC Windows locale

Usare Docker Desktop con backend WSL2, abilitare l'integrazione con la distribuzione WSL e conservare il repository in un percorso condiviso con Docker. È preferibile lavorare da PowerShell nella directory del progetto.

New-Item -ItemType Directory -Force "$HOME\.thothii\secrets" | Out-Null
foreach ($name in @("bootstrap", "migrator", "reader", "writer")) {
  $bytes = New-Object byte[] 32
  [Security.Cryptography.RandomNumberGenerator]::Fill($bytes)
  [Convert]::ToBase64String($bytes) | Set-Content -NoNewline "$HOME\.thothii\secrets\$name"
}
$env:THT_VECTOR_BOOTSTRAP_PASSWORD_SECRET_FILE = "$HOME\.thothii\secrets\bootstrap"
$env:THT_VECTOR_MIGRATOR_PASSWORD_SECRET_FILE = "$HOME\.thothii\secrets\migrator"
$env:THT_VECTOR_READER_PASSWORD_SECRET_FILE = "$HOME\.thothii\secrets\reader"
$env:THT_VECTOR_WRITER_PASSWORD_SECRET_FILE = "$HOME\.thothii\secrets\writer"
$env:THT_OLLAMA_URL = "http://host.docker.internal:11434"

Da PowerShell, i path assoluti vengono passati a Compose tramite le variabili precedenti; non scrivere password direttamente nello YAML. Avviare lo stesso profilo del Mac:

docker compose -f compose.yaml -f deploy/compose.local-vector.yaml `
  --profile local-vector up --build --wait
docker compose -f compose.yaml -f deploy/compose.local-vector.yaml `
  -f deploy/compose.preprocess.yaml -f deploy/compose.preprocess-local-vector.yaml `
  --profile local-vector --profile preprocess run --rm preprocess-evidence

Se Docker Desktop segnala un bind mount non condiviso, aggiungere la directory del repository in Docker Desktop → Settings → Resources → File Sharing. Se Ollama gira su Windows, usare host.docker.internal; se gira in WSL2, usare l'endpoint raggiungibile dalla rete Docker. Verificare il profilo con:

docker compose -f compose.yaml -f deploy/compose.local-vector.yaml --profile local-vector config
docker compose -f compose.yaml -f deploy/compose.local-vector.yaml --profile local-vector ps

4. Server applicativo distinto da DB e Evidence

Questo profilo separa il server Docker di ThothII dal DWH, vector DB e repository Evidence. Usare compose.production.yaml e configurare gli adapter con endpoint raggiungibili dal server applicativo. Le Evidence non devono essere copiate nel container se sono già accessibili via HTTP/S3 o tramite un filesystem montato dal sistema operativo.

Configurare firewall e DNS in modo che il server applicativo possa raggiungere solo gli endpoint necessari. Esempi di sorgente Evidence:

  • filesystem: NFS/SMB montato sul server e passato come root read-only al workspace;
  • http: URL HTTPS con allowlist/limiti SSRF e cache condizionata;
  • s3: bucket/prefix con secret references e endpoint custom solo con trust boundary esplicito.

Impostare THT_DOCS_ROOT/il workspace per il path montato oppure configurare il tipo HTTP/S3, poi avviare:

docker compose -f compose.yaml -f deploy/compose.production.yaml \
  --profile external config --quiet
docker compose -f compose.yaml -f deploy/compose.production.yaml \
  --profile external up --build --wait
docker compose -f compose.yaml -f deploy/compose.production.yaml \
  --profile external exec core /opt/venv/bin/tht doctor --json

Per un vector DB remoto usare le chiavi reader/writer distinte quando il servizio lo consente; per un DWH REST usare THT_DWH_REST_URL e il relativo secret, senza introdurre connessioni dirette nel container. Il preprocessing DWH/Evidence può essere eseguito sullo stesso server applicativo con un volume /data persistente, mantenendo separati i lock e gli artefatti dei job.

Controlli comuni post-installazione

  1. docker compose ... config --quiet non deve mostrare password o token in chiaro.
  2. docker compose ... ps deve mostrare core e frontend healthy.
  3. tht doctor --json deve restituire JSON valido; errori di dipendenza devono restare diagnostici e non esporre secret.
  4. Eseguire lo smoke coerente col profilo (docker-smoke.sh, preprocess-smoke.sh o local-vector-smoke.sh).
  5. Conservare il volume thoth_data e i backup pgvector fuori dal ciclo di deploy; usare down --volumes solo per ambienti effimeri o dopo aver verificato il backup.

Risoluzione rapida dei problemi

  • Core healthy ma nessun modello: controllare THT_MODEL_API_KEY_SECRET_FILE, il provider selezionato e che non sia uno dei provider composti non supportati.
  • Preprocess fallisce subito: verificare l'overlay compose.preprocess-local-vector.yaml, i quattro secret pgvector e che il mount Evidence sia leggibile.
  • Vector health non disponibile: controllare vector-db, vector-reconcile, vector-migrate e le password reader/writer; non usare la password bootstrap nelle query applicative.
  • Evidence non trovate: controllare il path nel workspace, la rete HTTP/S3 e i limiti di dimensione/paginazione; verificare che il corpus ACTIVE appartenga allo stesso workspace.