From 7f8346ff58e031c3c675c25b85d8c8f9ba995760 Mon Sep 17 00:00:00 2001 From: mptyl Date: Sun, 12 Jul 2026 10:21:53 +0200 Subject: [PATCH] docs: keep installation configuration inside ThothII --- .gitignore | 5 + deploy/env.example | 19 ++-- deploy/secrets/README.md | 16 +-- docs/installazione-docker-4-contesti.md | 125 ++++++++++++++++-------- 4 files changed, 111 insertions(+), 54 deletions(-) diff --git a/.gitignore b/.gitignore index 4c6cc7c9..bb12ea7c 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,11 @@ tools/replay/web/ ca-chain.pem config/ca-chain.pem +# ThothII deployment configuration and secret values (keep only the README tracked) +deploy/.env +deploy/secrets/* +!deploy/secrets/README.md + # === Runtime data (sessions contain PII; indexes are derived) === harness/sessions/ harness/indexes/ diff --git a/deploy/env.example b/deploy/env.example index 30a421cf..a9fe87ba 100644 --- a/deploy/env.example +++ b/deploy/env.example @@ -1,11 +1,12 @@ -# LOCAL DEVELOPMENT ONLY. Copy to deploy/.env and use deploy/compose.local.yaml. -# Never commit deploy/.env or real credentials. Production uses Compose secrets instead. +# LOCAL/PRODUCTION CONFIGURATION TEMPLATE. Copy to deploy/.env. +# Never commit deploy/.env or the files under deploy/secrets/. # Optional application defaults PI_PROVIDER= PI_MODEL= PI_THINKING= -THT_MODEL_API_KEY_FILE=/absolute/path/to/model_api_key +# Container-only path is assigned by deploy/compose.production.yaml. +THT_MODEL_API_KEY_SECRET_FILE=deploy/secrets/model-api-key MAX_PI_PROCESSES=4 AUTH_MODE=none @@ -13,11 +14,15 @@ AUTH_MODE=none THT_DB_NAME= THT_DWH_REST_URL= THT_DWH_API_KEY= +THT_DWH_API_KEY_SECRET_FILE=deploy/secrets/dwh-api-key # External vector service. Use a distinct write key where the service supports one. THT_VEC_REST_URL= THT_VEC_API_KEY= THT_VEC_WRITE_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_CA_SECRET_FILE=deploy/secrets/ca-chain.pem # Optional local-vector profile. Keep these secret files outside Git and readable by Docker. THT_VECTOR_DATABASE=thoth @@ -25,12 +30,12 @@ THT_VECTOR_BOOTSTRAP_USER=postgres THT_VECTOR_MIGRATOR_USER=thoth_vector_migrator THT_VECTOR_READER_USER=thoth_vector_reader THT_VECTOR_WRITER_USER=thoth_vector_writer -THT_VECTOR_BOOTSTRAP_PASSWORD_SECRET_FILE=/absolute/path/to/vector_bootstrap_password +THT_VECTOR_BOOTSTRAP_PASSWORD_SECRET_FILE=deploy/secrets/vector_bootstrap_password # Changing the file alone does not rotate an initialized DB; use # scripts/vector-rotate-bootstrap-password.sh OLD_SECRET_FILE NEW_SECRET_FILE. -THT_VECTOR_MIGRATOR_PASSWORD_SECRET_FILE=/absolute/path/to/vector_migrator_password -THT_VECTOR_READER_PASSWORD_SECRET_FILE=/absolute/path/to/vector_reader_password -THT_VECTOR_WRITER_PASSWORD_SECRET_FILE=/absolute/path/to/vector_writer_password +THT_VECTOR_MIGRATOR_PASSWORD_SECRET_FILE=deploy/secrets/vector_migrator_password +THT_VECTOR_READER_PASSWORD_SECRET_FILE=deploy/secrets/vector_reader_password +THT_VECTOR_WRITER_PASSWORD_SECRET_FILE=deploy/secrets/vector_writer_password # External embeddings service THT_OLLAMA_URL= diff --git a/deploy/secrets/README.md b/deploy/secrets/README.md index 7055e47c..4f5cb0e9 100644 --- a/deploy/secrets/README.md +++ b/deploy/secrets/README.md @@ -1,7 +1,9 @@ # Runtime secrets and private CA -Do not put secret values in this directory or in Git. For production, create files outside the -repository and point the `*_SECRET_FILE` variables documented in the root README at them. +Secret values in this directory are ignored by Git and remain local to the cloned `ThothII` +directory. This self-contained layout is the default installation documented in +`docs/installazione-docker-4-contesti.md`; an enterprise deployment may point the same +`*_SECRET_FILE` variables at an external secret-manager materialization instead. Compose mounts each file read-only beneath `/run/secrets`. The core process runs as UID 10001; the mounted files must be readable by that UID. Docker Compose file-backed secrets are normally @@ -21,8 +23,10 @@ one value with no surrounding quotes. reads it afresh for each Pi child and maps it to the selected provider's native environment name; the generic path/value is not placed in settings, health output, argv, or logs. Supported hosted providers include Anthropic, OpenAI, Google/Gemini, DeepSeek, Z.AI, Groq, Mistral, OpenRouter, -xAI, Cerebras, and Cohere. Local Ollama/LM Studio providers require no file. Unknown hosted -providers fail closed until an explicit mapping is added. +xAI, and Cerebras. Local Ollama/LM Studio providers require no file. Compound providers such as +Bedrock, Azure OpenAI Responses, and Cloudflare Workers AI/Gateway fail closed because they +require multiple credential/configuration values. Unknown hosted providers fail closed until an +explicit mapping is added. ## Rotating the initialized local-vector bootstrap password @@ -32,8 +36,8 @@ project: ```sh ./scripts/vector-rotate-bootstrap-password.sh \ - /absolute/path/to/current-bootstrap-secret \ - /absolute/path/to/staged-new-bootstrap-secret + deploy/secrets/vector_bootstrap_password \ + deploy/secrets/vector_bootstrap_password.next ``` The command authenticates using the current file, changes only the authenticated bootstrap role, diff --git a/docs/installazione-docker-4-contesti.md b/docs/installazione-docker-4-contesti.md index c25a61e6..a5b56e1b 100644 --- a/docs/installazione-docker-4-contesti.md +++ b/docs/installazione-docker-4-contesti.md @@ -23,18 +23,59 @@ Clonare il repository e lavorare dalla sua radice: ```sh git clone ThothII cd ThothII -cp deploy/env.example deploy/.env # solo per sviluppo locale +cp deploy/env.example deploy/.env +mkdir -p deploy/secrets deploy/workspaces +chmod 600 deploy/.env ``` -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. +La configurazione installativa rimane tutta dentro `ThothII/`: -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 +```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 +``` + +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/.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: + +```sh +set -a +. ./deploy/.env +set +a +``` + +In alternativa 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. @@ -53,17 +94,20 @@ nomi di servizio della rete Docker. ### Configurazione -Creare i file secret fuori dal repository. Prima si definiscono i percorsi host nelle variabili +Prima si definiscono in `ThothII/deploy/.env` i percorsi host nelle variabili `THT_*_SECRET_FILE`: -```sh -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 +```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 ``` +Queste righe vanno scritte nel file interno `ThothII/deploy/.env`, non eseguite solo +temporaneamente nella shell. + Nella forma documentale, i cinque target sono indicati come ``, ``, ``, `` e @@ -104,13 +148,11 @@ sudo sh -c 'umask 077; cat > "$1"' sh "$THT_DWH_API_KEY_SECRET_FILE" \ < /percorso/protetto/dwh-api-key ``` -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 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 @@ -119,10 +161,10 @@ usare `ConvertFrom-SecureString` come contenuto del file: produce una rappresent 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//.thothii/secrets +# Dentro WSL2, dalla directory radice del clone ThothII. +mkdir -p deploy/secrets umask 077 -read -r -s secret; printf '%s' "$secret" > /mnt/c/Users//.thothii/secrets/dwh-api-key +read -r -s secret; printf '%s' "$secret" > deploy/secrets/dwh-api-key unset secret ``` @@ -144,9 +186,9 @@ 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 +`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 `/etc/thothii/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 @@ -218,17 +260,17 @@ Questo è il profilo consigliato per un Mac Apple Silicon o Intel: Docker Deskto 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: +Creare quattro password locali dentro `ThothII/deploy/secrets/` (la directory è esclusa da Git): ```sh -mkdir -p ~/.thothii/secrets +mkdir -p deploy/secrets for name in bootstrap migrator reader writer; do - umask 077; openssl rand -base64 32 >"$HOME/.thothii/secrets/$name" + umask 077; openssl rand -base64 32 >"deploy/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_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 ``` @@ -267,16 +309,17 @@ conservare il repository in un percorso condiviso con Docker. È preferibile lav PowerShell nella directory del progetto. ```powershell -New-Item -ItemType Directory -Force "$HOME\.thothii\secrets" | Out-Null +$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 "$HOME\.thothii\secrets\$name" + [Convert]::ToBase64String($bytes) | Set-Content -NoNewline (Join-Path $secretDir $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_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" ```