# Installazione Docker nei quattro contesti operativi ThothII viene distribuito con due immagini applicative: - `thothii-core`: backend Fastify, harness `tht` e Pi; - `thothii-frontend`: frontend React servito da nginx. PostgreSQL/pgvector, DWH ed Evidence restano esterni nel profilo predefinito. Il profilo opzionale `local-vector` avvia PostgreSQL/pgvector nel progetto Compose. ## Installazione comune (il comando standard) Servono Docker Engine/Compose v2 su Linux oppure Docker Desktop su macOS/Windows. Dalla directory in cui si vuole conservare il clone: ```sh git clone ThothII cd ThothII cp deploy/env/local.env.example deploy/env/local.env cp deploy/secrets/thothii.secrets.example deploy/secrets/thothii.secrets chmod 600 deploy/secrets/thothii.secrets ``` Modificare **solo** questi file interni al clone: | File | Cosa contiene | |---|---| | `deploy/env/local.env` | endpoint, database e path Pi locali; mai password/token | | file protetti locali | credenziali e certificati, indicati dai binding del workspace | | `deploy/workspaces/.yaml` | adapter, endpoint non riservati, `roots` ed Evidence | Compilare `deploy/env/local.env`, inclusi i path assoluti `PI_AUTH_FILE` e `THT_SECRETS_FILE`, con gli endpoint esterni. L'avvio normale usa esplicitamente il file base e l'overlay locale: ```sh docker compose --env-file deploy/env/local.env \ -f compose.yaml -f deploy/compose.local.yaml up --build -d ``` Verificare lo stato con lo stesso comando Compose e aprire . Il core include Pi; il binario Pi non deve essere installato sull'host. `docker compose down` conserva i volumi; usare `down --volumes` solo per un ambiente effimero. ### Formato del bundle unico `deploy/secrets/thothii.secrets` è un file di testo locale, non uno script shell. Sono ammessi commenti e righe vuote; ogni altra riga deve essere una sola assegnazione senza spazi: ```dotenv THT_MODEL_API_KEY=... THT_DWH_API_KEY=... THT_VEC_API_KEY=... THT_VEC_WRITE_API_KEY=... THT_VECTOR_BOOTSTRAP_PASSWORD=... THT_VECTOR_MIGRATOR_PASSWORD=... THT_VECTOR_READER_PASSWORD=... THT_VECTOR_WRITER_PASSWORD=... ``` Inserire solo le chiavi necessarie al profilo scelto. Il bundle viene montato in sola lettura nel container come `/run/secrets/thothii.secrets`; il parser rifiuta duplicati, chiavi sconosciute, valori vuoti, symlink e permessi host troppo aperti. Non inserire secret in `.env`, nei workspace, negli URL o nell'output Compose renderizzato. Una catena CA PEM **non può essere inserita nel bundle**: contiene whitespace e viene rifiutata dal parser. Se un endpoint usa una CA privata, conservarla nel secret manager/host e aggiungere un override Compose revisionato che monti il file in `/run/secrets/ca-chain.pem` e imposti `THT_SSL_CA` (o il parametro dell'adapter). Il clone base non crea quel mount: questa è una limitazione intenzionale da considerare in fase di deployment. ### Overlay opzionali espliciti DWH/vector/embedding remoti restano endpoint del file locale o server. Per il solo preset di sviluppo pgvector, aggiungere `-f deploy/compose.local-vector.yaml --profile local-vector` al comando base. Per il preprocessing aggiungere anche `-f deploy/compose.preprocess.yaml -f deploy/compose.preprocess-local-vector.yaml --profile preprocess`, poi ripetere l'intero comando base con l'azione `run --rm preprocess-evidence` oppure `run --rm preprocess-dwh`. ## Workspace, adapter e Evidence Il workspace YAML seleziona il trasporto disponibile. Esempio DWH REST e vector DB HTTP: ```yaml language: en dwh: type: thoth_rest database: {database: warehouse, schema: datawarehouse} endpoint: {base_url: https://dwh.example.test} vectors: type: thoth_vector_http reader: {base_url: https://vectors.example.test} writer: {base_url: https://vectors.example.test} roots: {artifacts: artifacts, indexes: indexes, sessions: sessions} evidence: {source_root: /data/source, evidence_dir: evidence} embeddings: {base_url: https://embeddings.example.test, model: nomodel, dim: 768} ``` Esempio con accesso diretto a PostgreSQL e pgvector: ```yaml language: en dwh: type: postgres_direct connection: {host: dwh.internal, database: warehouse, schema: public, user: thoth_reader, password_file: /run/secrets/dwh_password} vectors: type: pgvector_direct reader: {host: vector.internal, database: thoth, schema: vectors, user: thoth_vector_reader, password_file: /run/secrets/vector_reader_password} writer: {host: vector.internal, database: thoth, schema: vectors, user: thoth_vector_writer, password_file: /run/secrets/vector_writer_password} roots: {artifacts: artifacts, indexes: indexes, sessions: sessions} ``` Questo esempio mostra il contratto dell'adapter: i file indicati da `password_file` devono essere montati da un override Compose approvato. Il profilo base monta soltanto il bundle unico; per un DWH diretto occorre quindi materializzare il file password dal secret manager e aggiungere il bind mount/runtime adapter corrispondente. Non inserire la password nel workspace o nell'URL. `roots` sono relativi e vengono risolti sotto `/data/workspaces/` nel volume Docker; non inserire path host come `/Users/...` o `C:\\...`. Per Evidence usare una radice filesystem montata in sola lettura oppure l'adapter HTTP/S3 previsto dal workspace. Per HTTP/S3 definire allowlist, limiti di dimensione/paginazione e una politica egress; non mettere token nelle URI. ## 1. Server remoto insieme ai database e al vector DB Usare quando il server Docker è nella stessa rete del DWH e del vector DB (containerizzati o meno). Compilare `deploy/env/local.env` con gli endpoint raggiungibili localmente: ```dotenv THT_DB_NAME=warehouse THT_DWH_REST_URL=https://dwh.internal.example THT_VEC_REST_URL=https://vectors.internal.example THT_OLLAMA_URL=https://embeddings.internal.example AUTH_MODE=none THOTH_PUBLIC_EXPOSURE=false ``` Riempire nel bundle le chiavi DWH/vector/model necessarie e avviare: ```sh docker compose --env-file deploy/env/local.env \ -f compose.yaml -f deploy/compose.local.yaml up --build -d docker compose --env-file deploy/env/local.env \ -f compose.yaml -f deploy/compose.local.yaml exec core /opt/venv/bin/tht doctor --json ``` Se si abilita l'overlay production, il proxy autenticato TLS deve essere l'unico listener pubblico e deve sostituire gli header client con i claim restituiti dal proprio `auth_request`. L'esempio usa header `X-Thoth-Trusted-*` soltanto sul collegamento privato; nginx frontend li converte nei claim normalizzati `X-Thoth-Principal-Issuer`, `X-Thoth-Principal-Subject`, `X-Thoth-Principal-Display-Name` e `X-Thoth-Is-Admin` attesi dal core. Non esporre direttamente la porta pubblicata da nginx. Se il server deve essere raggiungibile da altri host, usare il profilo `deploy/compose.server.yaml`, configurare il proxy autenticato e impostare `AUTH_MODE=upstream`/`THOTH_PUBLIC_EXPOSURE=true` come descritto nella sezione di trust boundary. ## 2. Mac locale Installare Docker Desktop e, se usato, Ollama sul Mac. In `deploy/env/local.env` impostare gli endpoint: ```dotenv THT_DB_NAME=warehouse THT_DWH_REST_URL=https://dwh.example.test THT_OLLAMA_URL=http://host.docker.internal:11434 THT_DOCS_ROOT=/data/source/evidence ``` Nel bundle aggiungere quattro password generate localmente: ```dotenv THT_VECTOR_BOOTSTRAP_PASSWORD= THT_VECTOR_MIGRATOR_PASSWORD= THT_VECTOR_READER_PASSWORD= THT_VECTOR_WRITER_PASSWORD= ``` Poi eseguire il comando standard base+locale mostrato sopra. Il primo avvio esegue reconciliation dei ruoli e migrazione pgvector. Per preprocessing, impostare il preset indicato sopra e usare l'azione `run --rm preprocess-evidence` o `run --rm preprocess-dwh` con tutti gli stessi file e profili. ## 3. PC Windows locale Usare Docker Desktop con backend WSL2 e abilitare la condivisione della directory del clone. Modificare `deploy/env/local.env`: ```dotenv THT_DB_NAME=warehouse THT_DWH_REST_URL=https://dwh.example.test THT_OLLAMA_URL=http://host.docker.internal:11434 THT_DOCS_ROOT=/data/source/evidence ``` Creare `deploy/secrets/thothii.secrets` con un editor locale protetto (ACL leggibile solo dall'utente Docker) e le stesse quattro chiavi pgvector del profilo Mac. Non usare `ConvertFrom-SecureString`: il bundle deve contenere il valore in chiaro per il servizio, con accesso limitato al file. Da PowerShell, dalla radice del clone, eseguire: ```powershell docker compose --env-file deploy/env/local.env -f compose.yaml -f deploy/compose.local.yaml up --build -d docker compose --env-file deploy/env/local.env -f compose.yaml -f deploy/compose.local.yaml ps ``` Se un bind mount viene rifiutato, aggiungere la cartella del repository a Docker Desktop → Settings → Resources → File Sharing. Per Ollama eseguito in WSL2 usare l'indirizzo raggiungibile dalla rete Docker invece di assumere `localhost`. ## 4. Server applicativo distinto da DB ed Evidence Usare il profilo server e consentire dal firewall solo le destinazioni necessarie: ```dotenv # Avvio: docker compose --env-file deploy/env/server.env \ # -f compose.yaml -f deploy/compose.server.yaml \ # -f deploy/compose.session-server.yaml.example up --build -d THT_DB_NAME=warehouse THT_DWH_REST_URL=https://dwh.example.test THT_VEC_REST_URL=https://vectors.example.test THT_OLLAMA_URL=https://embeddings.example.test ``` Avviare e verificare con il profilo server completo: ```sh docker compose --env-file deploy/env/server.env \ -f compose.yaml -f deploy/compose.server.yaml \ -f deploy/compose.session-server.yaml.example up --build -d docker compose --env-file deploy/env/server.env \ -f compose.yaml -f deploy/compose.server.yaml \ -f deploy/compose.session-server.yaml.example exec core /opt/venv/bin/tht doctor --json ``` Il DWH e il vector DB possono essere REST/HTTP oppure adapter diretti (`postgres_direct`, `pgvector_direct`) se il server ha connettività TCP. Le Evidence possono essere: - filesystem NFS/SMB montato sul server e presentato come root read-only; - endpoint HTTPS, con allowlist e limiti SSRF; - bucket S3 con secret references e endpoint custom esplicitamente autorizzati. Il preprocessing può girare sul server applicativo usando il volume `/data`; mantenere separati workspace, lock e artefatti dei job. Avviare con il comando standard e verificare `tht doctor`. ## Migrazione da installazioni con secret separati Le variabili `THT_*_SECRET_FILE` e i file `dwh-api-key`, `vector-reader-api-key`, `vector-writer-api-key`, `model-api-key` e `vector_*_password` appartengono al layout precedente. Non vengono importati automaticamente dal bundle. Per migrare: 1. creare `deploy/secrets/thothii.secrets` mode `0600`; 2. copiare ogni valore nel nome chiave corrispondente (`THT_DWH_API_KEY`, `THT_VEC_API_KEY`, `THT_VEC_WRITE_API_KEY`, `THT_MODEL_API_KEY` o `THT_VECTOR_*_PASSWORD`), senza virgolette né newline; 3. rimuovere dal `.env` le variabili `_SECRET_FILE` e impostare `THT_SECRETS_FILE` al percorso assoluto del bundle; 4. renderizzare e avviare con il comando base+locale completo e il suo `--env-file`; 5. solo dopo la verifica, cancellare i vecchi file separati. Una CA PEM resta un'eccezione esterna come descritto sopra. Provider Pi con credenziali composte (Bedrock, Azure OpenAI Responses, Cloudflare Workers AI/Gateway) restano rifiutati finché non viene implementato un adapter dedicato. ## Controlli post-installazione ```sh docker compose --env-file deploy/env/local.env \ -f compose.yaml -f deploy/compose.local.yaml config --quiet docker compose --env-file deploy/env/local.env \ -f compose.yaml -f deploy/compose.local.yaml ps docker compose --env-file deploy/env/local.env \ -f compose.yaml -f deploy/compose.local.yaml exec core /opt/venv/bin/tht doctor --json ./scripts/docker-smoke.sh ``` Per il profilo locale usare anche `./scripts/local-vector-smoke.sh`; per il preprocessing `./scripts/preprocess-smoke.sh`. Non pubblicare `.env` o `deploy/secrets/thothii.secrets` nei log, nei backup Git o nei ticket.