docs: document one-command Docker installation
This commit is contained in:
+3
-1
@@ -8,7 +8,9 @@ La documentazione è divisa in due aree:
|
||||
|
||||
Come funziona il sistema: architettura, specifiche di design delle singole funzionalità, piani di implementazione, report di test. Parte da qui: [Panoramica dell'architettura](architecture/overview.md).
|
||||
|
||||
Per installare l'applicazione in Docker nei diversi contesti operativi: [Installazione Docker nei quattro contesti](installazione-docker-4-contesti.md).
|
||||
Per installare l'applicazione in Docker nei quattro contesti operativi, partendo dal comando
|
||||
predefinito `docker compose up --build -d` e dal bundle unico dei secret:
|
||||
[Installazione Docker nei quattro contesti](installazione-docker-4-contesti.md).
|
||||
|
||||
## Considerazioni Generali
|
||||
|
||||
|
||||
@@ -1,433 +1,227 @@
|
||||
# Installazione Docker nei quattro contesti operativi
|
||||
|
||||
Questa guida descrive l'installazione di ThothII usando le due immagini applicative:
|
||||
ThothII viene distribuito con 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.
|
||||
PostgreSQL/pgvector, DWH ed Evidence restano esterni nel profilo predefinito. Il profilo opzionale `local-vector` avvia PostgreSQL/pgvector nel progetto Compose.
|
||||
|
||||
## Prerequisiti comuni
|
||||
## Installazione comune (il comando standard)
|
||||
|
||||
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:
|
||||
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 <URL-REPOSITORY> ThothII
|
||||
cd ThothII
|
||||
cp deploy/env.example deploy/.env
|
||||
cp .env.example .env
|
||||
mkdir -p deploy/secrets deploy/workspaces
|
||||
chmod 600 deploy/.env
|
||||
cp deploy/secrets/thothii.secrets.example deploy/secrets/thothii.secrets
|
||||
chmod 600 deploy/secrets/thothii.secrets
|
||||
```
|
||||
|
||||
La configurazione installativa rimane tutta dentro `ThothII/`:
|
||||
Modificare **solo** questi file interni al clone:
|
||||
|
||||
```text
|
||||
ThothII/
|
||||
├── deploy/.env # riferimenti ai file e valori non riservati
|
||||
├── deploy/secrets/ # file secret locali, esclusi da Git
|
||||
└── deploy/workspaces/ # workspace YAML senza password/token
|
||||
```
|
||||
| File | Cosa contiene |
|
||||
|---|---|
|
||||
| `.env` | endpoint, database, provider, `COMPOSE_FILE` e `COMPOSE_PROFILES`; mai password/token |
|
||||
| `deploy/secrets/thothii.secrets` | un bundle `NOME=VALORE`, mode host `0600` o `0400` |
|
||||
| `deploy/workspaces/<nome>.yaml` | adapter, endpoint non riservati, `roots` ed Evidence |
|
||||
|
||||
I soli file da creare o modificare dopo il clone sono questi:
|
||||
|
||||
| File interno a `ThothII/` | Operazione | Contenuto |
|
||||
|---|---|---|
|
||||
| `deploy/.env` | copiare da `deploy/env.example` e modificare | endpoint, nomi, profili e percorsi relativi dei secret |
|
||||
| `deploy/secrets/dwh-api-key` | creare | una API key DWH, una riga/valore |
|
||||
| `deploy/secrets/dwh_password` | creare solo con `postgres_direct` | password dell'utente DWH diretto |
|
||||
| `deploy/secrets/vector-reader-api-key` | creare | chiave reader vector REST, se usata |
|
||||
| `deploy/secrets/vector-writer-api-key` | creare | chiave writer vector REST, se usata |
|
||||
| `deploy/secrets/model-api-key` | creare | chiave del provider Pi a chiave singola |
|
||||
| `deploy/secrets/ca-chain.pem` | creare, se serve TLS privato | catena CA PEM pubblica |
|
||||
| `deploy/secrets/vector_bootstrap_password` | creare con `local-vector` | password bootstrap pgvector |
|
||||
| `deploy/secrets/vector_migrator_password` | creare con `local-vector` | password migrator |
|
||||
| `deploy/secrets/vector_reader_password` | creare con `local-vector` | password reader pgvector |
|
||||
| `deploy/secrets/vector_writer_password` | creare con `local-vector` | password writer pgvector |
|
||||
| `deploy/workspaces/<nome>.yaml` | copiare/modificare | adapter, endpoint non riservati, `roots` e sorgente Evidence |
|
||||
|
||||
Non occorre creare file in `/etc`, `/opt`, `~/.thothii` o in altre directory esterne per seguire
|
||||
questa guida. I file secret sono ignorati da Git tramite `.gitignore`, ma restano disponibili a
|
||||
Docker perché Compose li legge dal progetto locale.
|
||||
|
||||
I secret non devono essere inseriti in `deploy/.env`, nei file workspace o negli URL.
|
||||
`deploy/.env` contiene solo host, porte, nomi di database e percorsi relativi come
|
||||
`THT_DWH_API_KEY_SECRET_FILE=deploy/secrets/dwh-api-key`. 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. Dopo aver modificato `deploy/.env`, caricarlo nella shell da
|
||||
cui si eseguono i comandi Docker:
|
||||
Il file `.env` viene caricato automaticamente da Docker Compose perché è nella radice del progetto. Il valore predefinito è `COMPOSE_FILE=compose.yaml`, con profili vuoti e `THT_SECRETS_FILE=deploy/secrets/thothii.secrets`. Perciò, dopo aver compilato `.env`, il bundle e almeno il workspace, l'avvio normale è sempre:
|
||||
|
||||
```sh
|
||||
set -a
|
||||
. ./deploy/.env
|
||||
set +a
|
||||
docker compose up --build -d
|
||||
```
|
||||
|
||||
Le tre righe fanno questo:
|
||||
Non occorre usare `--env-file`, `-f` o `--profile` per questa installazione. Verificare lo stato con `docker compose ps` e aprire <http://127.0.0.1:8080>. `docker compose down` conserva il volume `thoth_data`; usare `down --volumes` solo per un ambiente effimero.
|
||||
|
||||
1. `set -a` dice alla shell di esportare automaticamente tutte le variabili assegnate da
|
||||
questo momento in poi;
|
||||
2. `. ./deploy/.env` (il punto iniziale è l'abbreviazione di `source`) legge ed esegue il file
|
||||
nella shell corrente. Le variabili diventano quindi disponibili a `docker compose` e ai
|
||||
processi figli, senza aprire una nuova shell;
|
||||
3. `set +a` disattiva l'esportazione automatica per evitare che assegnazioni successive vengano
|
||||
esportate accidentalmente.
|
||||
### Formato del bundle unico
|
||||
|
||||
Esempio: se `deploy/.env` contiene
|
||||
`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_SECRET_FILE=deploy/secrets/model-api-key
|
||||
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=...
|
||||
```
|
||||
|
||||
dopo il comando `source` la shell possiede `THT_MODEL_API_KEY_SECRET_FILE` e Compose può usare
|
||||
quel percorso per leggere il secret file. Il valore della API key non viene caricato in
|
||||
`deploy/.env`: resta nel file separato sotto `deploy/secrets/`.
|
||||
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 di `docker compose config`.
|
||||
|
||||
La forma equivalente, senza modificare l'ambiente della shell, è passare il file direttamente a
|
||||
Compose:
|
||||
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.
|
||||
|
||||
```sh
|
||||
docker compose --env-file deploy/.env -f compose.yaml -f deploy/compose.production.yaml \
|
||||
--profile external up --build --wait
|
||||
```
|
||||
### Overlay opzionali tramite `.env`
|
||||
|
||||
Non usare `source`/`.` con file ricevuti da terzi senza averne verificato il contenuto: un file
|
||||
`.env` sourced è codice shell, non un semplice formato dati. In questa guida il file viene creato
|
||||
localmente da `deploy/env.example` e contiene solo assegnazioni di configurazione e percorsi.
|
||||
|
||||
Per i comandi successivi si può quindi scegliere una sola delle due modalità: fare `source`
|
||||
una volta all'inizio della sessione, oppure aggiungere `--env-file deploy/.env` a ogni comando
|
||||
`docker compose`.
|
||||
|
||||
Salvare invece ogni credenziale in un file separato dentro `ThothII/deploy/secrets/`. 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
|
||||
|
||||
Prima si definiscono in `ThothII/deploy/.env` i percorsi host nelle variabili
|
||||
`THT_*_SECRET_FILE`:
|
||||
Gli overlay non cambiano il comando operativo. Impostare in `.env`:
|
||||
|
||||
```dotenv
|
||||
THT_DWH_API_KEY_SECRET_FILE=deploy/secrets/dwh-api-key
|
||||
THT_VEC_API_KEY_SECRET_FILE=deploy/secrets/vector-reader-api-key
|
||||
THT_VEC_WRITE_API_KEY_SECRET_FILE=deploy/secrets/vector-writer-api-key
|
||||
THT_MODEL_API_KEY_SECRET_FILE=deploy/secrets/model-api-key
|
||||
THT_CA_SECRET_FILE=deploy/secrets/ca-chain.pem
|
||||
# DWH/vector/embedding remoti (server applicativo o server con i DB):
|
||||
COMPOSE_FILE=compose.yaml:deploy/compose.production.yaml
|
||||
COMPOSE_PROFILES=
|
||||
|
||||
# pgvector locale (Mac, Windows o server autonomo):
|
||||
COMPOSE_FILE=compose.yaml:deploy/compose.local-vector.yaml
|
||||
COMPOSE_PROFILES=local-vector
|
||||
```
|
||||
|
||||
Queste righe vanno scritte nel file interno `ThothII/deploy/.env`, non eseguite solo
|
||||
temporaneamente nella shell.
|
||||
Su Windows usare `;` come separatore di `COMPOSE_FILE`. Per il preprocessing locale aggiungere `deploy/compose.preprocess.yaml:deploy/compose.preprocess-local-vector.yaml` e impostare `COMPOSE_PROFILES=local-vector,preprocess`; poi usare `docker compose run --rm preprocess-evidence` oppure `docker compose run --rm preprocess-dwh`.
|
||||
|
||||
Nella forma documentale, i cinque target sono indicati come
|
||||
`<THT_DWH_API_KEY_SECRET_FILE>`, `<THT_VEC_API_KEY_SECRET_FILE>`,
|
||||
`<THT_VEC_WRITE_API_KEY_SECRET_FILE>`, `<THT_MODEL_API_KEY_SECRET_FILE>` e
|
||||
`<THT_CA_SECRET_FILE>`. Le parentesi angolari sono segnaposto e **non** vanno digitate nella
|
||||
shell: nei comandi eseguibili si usano le variabili tra virgolette doppie:
|
||||
## Workspace, adapter e Evidence
|
||||
|
||||
```sh
|
||||
for secret_file in \
|
||||
"$THT_DWH_API_KEY_SECRET_FILE" "$THT_VEC_API_KEY_SECRET_FILE" \
|
||||
"$THT_VEC_WRITE_API_KEY_SECRET_FILE" "$THT_MODEL_API_KEY_SECRET_FILE" "$THT_CA_SECRET_FILE"; do
|
||||
sudo install -d -m 700 "$(dirname "$secret_file")"
|
||||
done
|
||||
sudo install -m 600 /dev/null "$THT_DWH_API_KEY_SECRET_FILE"
|
||||
sudo install -m 600 /dev/null "$THT_VEC_API_KEY_SECRET_FILE"
|
||||
sudo install -m 600 /dev/null "$THT_VEC_WRITE_API_KEY_SECRET_FILE"
|
||||
sudo install -m 600 /dev/null "$THT_MODEL_API_KEY_SECRET_FILE"
|
||||
sudo install -m 600 /dev/null "$THT_CA_SECRET_FILE"
|
||||
```
|
||||
|
||||
Così ogni `sudo install` usa la variabile corretta e non si rischia di creare il file in un
|
||||
percorso diverso da quello che Compose leggerà. Se i secret sono forniti da un secret manager,
|
||||
si impostano le stesse variabili ai file materializzati dal manager e si saltano i comandi
|
||||
`install`.
|
||||
|
||||
`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.
|
||||
|
||||
Dopo la creazione, scrivere il contenuto in ogni target (l'esempio seguente usa un file sorgente
|
||||
protetto; ripeterlo per le altre variabili):
|
||||
|
||||
```sh
|
||||
sudo sh -c 'umask 077; cat > "$1"' sh "$THT_DWH_API_KEY_SECRET_FILE" \
|
||||
< /percorso/protetto/dwh-api-key
|
||||
```
|
||||
|
||||
Il percorso `deploy/secrets/` è la directory interna al clone usata da questa guida: il software
|
||||
non cerca automaticamente le API key in `/etc` né in una directory speciale. 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`.
|
||||
|
||||
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, dalla directory radice del clone ThothII.
|
||||
mkdir -p deploy/secrets
|
||||
umask 077
|
||||
read -r -s secret; printf '%s' "$secret" > deploy/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 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=deploy/secrets/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 il file host sotto `deploy/secrets`.
|
||||
|
||||
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:
|
||||
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.internal.example}
|
||||
endpoint: {base_url: https://dwh.example.test}
|
||||
vectors:
|
||||
type: thoth_vector_http
|
||||
reader: {base_url: https://vectors.internal.example}
|
||||
writer: {base_url: https://vectors.internal.example}
|
||||
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.internal.example, model: nomodel, dim: 768}
|
||||
embeddings: {base_url: https://embeddings.example.test, model: nomodel, dim: 768}
|
||||
```
|
||||
|
||||
Con DWH PostgreSQL e pgvector raggiungibili direttamente dalla rete Docker:
|
||||
Esempio con accesso diretto a PostgreSQL e pgvector:
|
||||
|
||||
```yaml
|
||||
language: en
|
||||
dwh:
|
||||
type: postgres_direct
|
||||
connection: {host: dwh.internal.example, database: warehouse, schema: public,
|
||||
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.example, database: thoth, schema: vectors,
|
||||
reader: {host: vector.internal, database: thoth, schema: vectors,
|
||||
user: thoth_vector_reader, password_file: /run/secrets/vector_reader_password}
|
||||
writer: {host: vector.internal.example, database: thoth, schema: vectors,
|
||||
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}
|
||||
```
|
||||
|
||||
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.
|
||||
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` 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.
|
||||
`roots` sono relativi e vengono risolti sotto `/data/workspaces/<workspace>` 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.
|
||||
|
||||
### Avvio e verifica
|
||||
## 1. Server remoto insieme ai database e al vector DB
|
||||
|
||||
```sh
|
||||
docker compose -f compose.yaml -f deploy/compose.production.yaml \
|
||||
--profile external up --build --wait
|
||||
Usare quando il server Docker è nella stessa rete del DWH e del vector DB (containerizzati o meno). Il file `.env` può restare sul default, senza profili, impostando gli endpoint raggiungibili localmente:
|
||||
|
||||
docker compose -f compose.yaml -f deploy/compose.production.yaml \
|
||||
--profile external exec core /opt/venv/bin/tht doctor --json
|
||||
./scripts/docker-smoke.sh
|
||||
```dotenv
|
||||
COMPOSE_FILE=compose.yaml
|
||||
COMPOSE_PROFILES=
|
||||
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
|
||||
```
|
||||
|
||||
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 dentro `ThothII/deploy/secrets/` (la directory è esclusa da Git):
|
||||
Riempire nel bundle le chiavi DWH/vector/model necessarie e avviare:
|
||||
|
||||
```sh
|
||||
mkdir -p deploy/secrets
|
||||
for name in bootstrap migrator reader writer; do
|
||||
umask 077; openssl rand -base64 32 >"deploy/secrets/$name"
|
||||
done
|
||||
export THT_VECTOR_BOOTSTRAP_PASSWORD_SECRET_FILE=deploy/secrets/bootstrap
|
||||
export THT_VECTOR_MIGRATOR_PASSWORD_SECRET_FILE=deploy/secrets/migrator
|
||||
export THT_VECTOR_READER_PASSWORD_SECRET_FILE=deploy/secrets/reader
|
||||
export THT_VECTOR_WRITER_PASSWORD_SECRET_FILE=deploy/secrets/writer
|
||||
export THT_OLLAMA_URL=http://host.docker.internal:11434
|
||||
docker compose up --build -d
|
||||
docker compose exec core /opt/venv/bin/tht doctor --json
|
||||
```
|
||||
|
||||
Avviare il profilo:
|
||||
Se si abilita l'overlay production, il proxy autenticato TLS deve essere l'unico listener pubblico
|
||||
e deve iniettare `X-Authenticated-User`; non esporre direttamente la porta pubblicata da nginx.
|
||||
|
||||
```sh
|
||||
docker compose -f compose.yaml -f deploy/compose.local-vector.yaml \
|
||||
--profile local-vector up --build --wait
|
||||
Se il server deve essere raggiungibile da altri host, sostituire `COMPOSE_FILE` con
|
||||
`compose.yaml:deploy/compose.production.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. Nel `.env` selezionare il profilo locale:
|
||||
|
||||
```dotenv
|
||||
COMPOSE_FILE=compose.yaml:deploy/compose.local-vector.yaml
|
||||
COMPOSE_PROFILES=local-vector
|
||||
THT_OLLAMA_URL=http://host.docker.internal:11434
|
||||
```
|
||||
|
||||
Per eseguire i job di preprocessing usare anche l'overlay che abilita la catena
|
||||
health-check → reconcile → migrate:
|
||||
Nel bundle aggiungere quattro password generate localmente:
|
||||
|
||||
```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
|
||||
```dotenv
|
||||
THT_VECTOR_BOOTSTRAP_PASSWORD=<valore casuale>
|
||||
THT_VECTOR_MIGRATOR_PASSWORD=<valore casuale>
|
||||
THT_VECTOR_READER_PASSWORD=<valore casuale>
|
||||
THT_VECTOR_WRITER_PASSWORD=<valore casuale>
|
||||
```
|
||||
|
||||
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
|
||||
```
|
||||
Poi eseguire il comando standard `docker compose up --build -d`. Il primo avvio esegue reconciliation dei ruoli e migrazione pgvector. Per preprocessing, impostare il preset indicato sopra e usare `docker compose run --rm preprocess-evidence`/`preprocess-dwh`.
|
||||
|
||||
## 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.
|
||||
Usare Docker Desktop con backend WSL2 e abilitare la condivisione della directory del clone. Modificare `.env` con il separatore Windows:
|
||||
|
||||
```powershell
|
||||
$secretDir = Join-Path (Get-Location) "deploy\secrets"
|
||||
New-Item -ItemType Directory -Force $secretDir | 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 (Join-Path $secretDir $name)
|
||||
}
|
||||
$env:THT_VECTOR_BOOTSTRAP_PASSWORD_SECRET_FILE = Join-Path $secretDir "bootstrap"
|
||||
$env:THT_VECTOR_MIGRATOR_PASSWORD_SECRET_FILE = Join-Path $secretDir "migrator"
|
||||
$env:THT_VECTOR_READER_PASSWORD_SECRET_FILE = Join-Path $secretDir "reader"
|
||||
$env:THT_VECTOR_WRITER_PASSWORD_SECRET_FILE = Join-Path $secretDir "writer"
|
||||
$env:THT_OLLAMA_URL = "http://host.docker.internal:11434"
|
||||
```dotenv
|
||||
COMPOSE_FILE=compose.yaml;deploy/compose.local-vector.yaml
|
||||
COMPOSE_PROFILES=local-vector
|
||||
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:
|
||||
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 -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
|
||||
docker compose up --build -d
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
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:
|
||||
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`.
|
||||
|
||||
```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 ed Evidence
|
||||
|
||||
Usare il profilo production e consentire dal firewall solo le destinazioni necessarie:
|
||||
|
||||
```dotenv
|
||||
COMPOSE_FILE=compose.yaml:deploy/compose.production.yaml
|
||||
COMPOSE_PROFILES=
|
||||
THT_DWH_REST_URL=https://dwh.example.test
|
||||
THT_VEC_REST_URL=https://vectors.example.test
|
||||
THT_OLLAMA_URL=https://embeddings.example.test
|
||||
```
|
||||
|
||||
## 4. Server applicativo distinto da DB e Evidence
|
||||
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:
|
||||
|
||||
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.
|
||||
- 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.
|
||||
|
||||
Configurare firewall e DNS in modo che il server applicativo possa raggiungere solo gli endpoint
|
||||
necessari. Esempi di sorgente Evidence:
|
||||
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`.
|
||||
|
||||
- `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.
|
||||
## Migrazione da installazioni con secret separati
|
||||
|
||||
Impostare `THT_DOCS_ROOT`/il workspace per il path montato oppure configurare il tipo HTTP/S3,
|
||||
poi avviare:
|
||||
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 del bundle (il default relativo è già corretto);
|
||||
4. eseguire `docker compose config --quiet` e poi `docker compose up --build -d`;
|
||||
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 -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
|
||||
docker compose config --quiet
|
||||
docker compose ps
|
||||
docker compose exec core /opt/venv/bin/tht doctor --json
|
||||
./scripts/docker-smoke.sh
|
||||
```
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user