refactor: retire external vector deployment

This commit is contained in:
2026-08-08 19:05:57 +02:00
parent 8f4ec1e1a3
commit 4e3fecbe8e
44 changed files with 370 additions and 1710 deletions
@@ -5,9 +5,3 @@ THT_WS_NORTH_STAR_RESEARCH_DWH_HOST=dwh.internal.example
THT_WS_NORTH_STAR_RESEARCH_DWH_PORT=5432
THT_WS_NORTH_STAR_RESEARCH_DWH_USER=thoth_reader
THT_WS_NORTH_STAR_RESEARCH_DWH_PASSWORD_FILE=/run/secrets/north-star-research-dwh-password
THT_WS_NORTH_STAR_RESEARCH_VECTOR_TRANSPORT=pgvector_direct
THT_WS_NORTH_STAR_RESEARCH_VECTOR_HOST=vector.internal.example
THT_WS_NORTH_STAR_RESEARCH_VECTOR_PORT=5432
THT_WS_NORTH_STAR_RESEARCH_VECTOR_USER=thoth_vector_reader
THT_WS_NORTH_STAR_RESEARCH_VECTOR_PASSWORD_FILE=/run/secrets/north-star-research-vector-password
THT_WS_NORTH_STAR_RESEARCH_EMBEDDING_BASE_URL=https://embeddings.internal.example
+6 -18
View File
@@ -80,30 +80,21 @@ is `THT_WS_<NAMESPACE>_<ROLE>_<SUFFIX>`. Copy
[the bindings env example](examples/workspace-bindings.env.example) to an untracked operator file
and set its absolute path as `THT_WORKSPACE_BINDINGS_ENV_FILE`. It is loaded only into `core`.
Credentials and certificates use `*_FILE` path variables that must point inside `/run/secrets`.
If declared, `THT_WS_NORTH_STAR_RESEARCH_VECTOR_WRITER_API_KEY_FILE` is distinct from the vector reader
file; a reader credential is never repurposed for writing.
## Direct PostgreSQL, REST, and SSH tunnel bindings
Set only fields for the selected transport in the dedicated bindings env file. Canonical YAML keeps
database/schema/collection, distance, embedding model, and dimensions shared in Git. Every
`*_FILE=/run/secrets/<target>` binding needs one matching host-only `*_SOURCE` path in operator
`.env`. Generate the untracked connector override from those two files during bootstrap; do not
copy or maintain a workspace-specific Compose override.
database/schema shared in Git. Every `*_FILE=/run/secrets/<target>` binding needs one matching
host-only `*_SOURCE` path in operator `.env`. Generate the untracked connector override from those
two files during bootstrap; do not copy or maintain a workspace-specific Compose override.
```dotenv
# Direct PostgreSQL and pgvector
# Direct PostgreSQL
THT_WS_NORTH_STAR_RESEARCH_DWH_TRANSPORT=postgres_direct
THT_WS_NORTH_STAR_RESEARCH_DWH_HOST=dwh.example.invalid
THT_WS_NORTH_STAR_RESEARCH_DWH_PORT=5432
THT_WS_NORTH_STAR_RESEARCH_DWH_USER=thoth_reader
THT_WS_NORTH_STAR_RESEARCH_DWH_PASSWORD_FILE=/run/secrets/north-star-research-dwh-password
THT_WS_NORTH_STAR_RESEARCH_VECTOR_TRANSPORT=pgvector_direct
THT_WS_NORTH_STAR_RESEARCH_VECTOR_HOST=vector.example.invalid
THT_WS_NORTH_STAR_RESEARCH_VECTOR_PORT=5432
THT_WS_NORTH_STAR_RESEARCH_VECTOR_USER=thoth_vector_reader
THT_WS_NORTH_STAR_RESEARCH_VECTOR_PASSWORD_FILE=/run/secrets/north-star-research-vector-password
THT_WS_NORTH_STAR_RESEARCH_EMBEDDING_BASE_URL=https://embeddings.example.invalid
```
```dotenv
@@ -111,9 +102,6 @@ THT_WS_NORTH_STAR_RESEARCH_EMBEDDING_BASE_URL=https://embeddings.example.invalid
THT_WS_NORTH_STAR_RESEARCH_DWH_TRANSPORT=rest_api
THT_WS_NORTH_STAR_RESEARCH_DWH_BASE_URL=https://dwh.example.invalid
THT_WS_NORTH_STAR_RESEARCH_DWH_API_KEY_FILE=/run/secrets/north-star-research-dwh-api-key
THT_WS_NORTH_STAR_RESEARCH_VECTOR_TRANSPORT=rest_api
THT_WS_NORTH_STAR_RESEARCH_VECTOR_BASE_URL=https://vectors.example.invalid
THT_WS_NORTH_STAR_RESEARCH_VECTOR_API_KEY_FILE=/run/secrets/north-star-research-vector-api-key
```
```dotenv
@@ -130,8 +118,8 @@ THT_WS_NORTH_STAR_RESEARCH_DWH_SSH_TARGET_HOST=dwh.internal.example
THT_WS_NORTH_STAR_RESEARCH_DWH_SSH_TARGET_PORT=5432
```
Repeat the SSH names for `VECTOR` where needed. REST diagnostics reject a private per-request CA
rather than weakening TLS; use runtime-trusted HTTPS or verified direct/SSH native TLS. See the
REST diagnostics reject a private per-request CA rather than weakening TLS; use runtime-trusted
HTTPS or verified direct/SSH native TLS. See the
[diagnostic protocol](../workspace-diagnostic-protocol.md).
An SSH connector can prove installation reachability, host-key verification, authentication, and
+2 -11
View File
@@ -109,17 +109,12 @@ Select only a transport allowed by canonical YAML; preserve database/schema/coll
dimensions, and distance as Git-shared identity.
```dotenv
# Direct PostgreSQL/pgvector with verified native TLS if a CA path is supplied.
# Direct PostgreSQL with verified native TLS if a CA path is supplied.
THT_WS_NORTH_STAR_RESEARCH_DWH_TRANSPORT=postgres_direct
THT_WS_NORTH_STAR_RESEARCH_DWH_HOST=dwh.internal.example
THT_WS_NORTH_STAR_RESEARCH_DWH_PORT=5432
THT_WS_NORTH_STAR_RESEARCH_DWH_USER=thoth_reader
THT_WS_NORTH_STAR_RESEARCH_DWH_PASSWORD_FILE=/run/secrets/north-star-research-dwh-password
THT_WS_NORTH_STAR_RESEARCH_VECTOR_TRANSPORT=pgvector_direct
THT_WS_NORTH_STAR_RESEARCH_VECTOR_HOST=vector.internal.example
THT_WS_NORTH_STAR_RESEARCH_VECTOR_PORT=5432
THT_WS_NORTH_STAR_RESEARCH_VECTOR_USER=thoth_vector_reader
THT_WS_NORTH_STAR_RESEARCH_VECTOR_PASSWORD_FILE=/run/secrets/north-star-research-vector-password
```
```dotenv
@@ -127,10 +122,6 @@ THT_WS_NORTH_STAR_RESEARCH_VECTOR_PASSWORD_FILE=/run/secrets/north-star-research
THT_WS_NORTH_STAR_RESEARCH_DWH_TRANSPORT=rest_api
THT_WS_NORTH_STAR_RESEARCH_DWH_BASE_URL=https://dwh.internal.example
THT_WS_NORTH_STAR_RESEARCH_DWH_API_KEY_FILE=/run/secrets/north-star-research-dwh-api-key
THT_WS_NORTH_STAR_RESEARCH_VECTOR_TRANSPORT=rest_api
THT_WS_NORTH_STAR_RESEARCH_VECTOR_BASE_URL=https://vectors.internal.example
THT_WS_NORTH_STAR_RESEARCH_VECTOR_API_KEY_FILE=/run/secrets/north-star-research-vector-api-key
THT_WS_NORTH_STAR_RESEARCH_EMBEDDING_BASE_URL=https://embeddings.internal.example
```
```dotenv
@@ -147,7 +138,7 @@ THT_WS_NORTH_STAR_RESEARCH_DWH_SSH_TARGET_HOST=dwh.internal.example
THT_WS_NORTH_STAR_RESEARCH_DWH_SSH_TARGET_PORT=5432
```
Repeat SSH variables for `VECTOR` when selected. REST diagnostics refuse private per-request CAs
REST diagnostics refuse private per-request CAs
rather than disable verification; use runtime-trusted HTTPS or verified direct/SSH native TLS. See
the [diagnostic protocol](../workspace-diagnostic-protocol.md) for its read-only checks and optional
reversible writer probe.
+39 -211
View File
@@ -1,250 +1,78 @@
# Installazione Docker nei quattro contesti operativi
# Installazione Docker nei contesti operativi correnti
ThothII viene distribuito con due immagini applicative:
ThothII usa una topologia Compose unica:
- `thothii-core`: backend Fastify, harness `tht` e Pi;
- `thothii-frontend`: frontend React servito da nginx.
- `frontend`
- `core`
- `qdrant`
- `embedding`
- `embedding-model-init`
PostgreSQL/pgvector, DWH ed Evidence restano esterni nel profilo predefinito. Il profilo opzionale `local-vector` avvia PostgreSQL/pgvector nel progetto Compose.
Qdrant e Ollama embedding sono servizi interni obbligatori del progetto Compose. Restano
esterni solo DWH e LLM.
## 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:
## Comando standard locale
```sh
git clone <URL-REPOSITORY> 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/<nome>.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 <http://127.0.0.1:8080>. 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.
Compilare `deploy/env/local.env` con:
### Formato del bundle unico
- `PI_AUTH_FILE`
- `THT_SECRETS_FILE`
- `THT_WORKSPACE_GIT_REMOTE`
- endpoint DWH
- endpoint LLM
`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:
Non inserire secret nel file `.env`. I secret runtime stanno nel bundle
`deploy/secrets/thothii.secrets`.
## Bundle dei secret
Le chiavi documentate e supportate nel bundle sono:
```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 CA privata PEM resta esterna al bundle e va montata con un override Compose revisionato.
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.
## Preprocessing
### 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/<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.
## 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:
I job di preprocessing usano gli stessi servizi interni Qdrant/Ollama:
```sh
docker compose --env-file deploy/env/local.env \
-f compose.yaml -f deploy/compose.local.yaml up --build -d
-f compose.yaml -f deploy/compose.local.yaml \
-f deploy/compose.preprocess.yaml --profile preprocess run --rm preprocess-evidence
```
Per introspezione DWH:
```sh
docker compose --env-file deploy/env/local.env \
-f compose.yaml -f deploy/compose.local.yaml exec core /opt/venv/bin/tht doctor --json
-f compose.yaml -f deploy/compose.local.yaml \
-f deploy/compose.preprocess.yaml --profile preprocess run --rm preprocess-dwh
```
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.
## Server
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=<valore casuale>
THT_VECTOR_MIGRATOR_PASSWORD=<valore casuale>
THT_VECTOR_READER_PASSWORD=<valore casuale>
THT_VECTOR_WRITER_PASSWORD=<valore casuale>
```
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:
Per installazioni server usare il profilo server con overlay sessioni:
```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:
Consultare anche:
- 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.
- `docs/install/local-workspace-registry.md`
- `docs/install/server-workspace-registry.md`