334 lines
16 KiB
Markdown
334 lines
16 KiB
Markdown
# 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:
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
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.
|
|
|
|
```sh
|
|
# 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):
|
|
|
|
```sh
|
|
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:
|
|
|
|
```yaml
|
|
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:
|
|
|
|
```yaml
|
|
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
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
./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.
|
|
|
|
```powershell
|
|
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:
|
|
|
|
```powershell
|
|
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:
|
|
|
|
```powershell
|
|
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:
|
|
|
|
```sh
|
|
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.
|