docs: add workspace registry installation manuals
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# Standalone local registry example. Copy beside the clone as compose.workspace-registry.yaml
|
||||
# and put path-only bindings in .env; keep the referenced files outside Git.
|
||||
name: thothii-workspace-registry-local
|
||||
|
||||
services:
|
||||
core:
|
||||
image: thothii-core:local
|
||||
build:
|
||||
context: ../../..
|
||||
dockerfile: docker/core.Dockerfile
|
||||
environment:
|
||||
HOST: 0.0.0.0
|
||||
PORT: "8787"
|
||||
AUTH_MODE: none
|
||||
THT_SESSION_STORAGE: local
|
||||
THT_HOME: /data/local-home
|
||||
SETTINGS_FILE: /data/settings/settings.json
|
||||
THT_HARNESS_DIR: /app/harness
|
||||
THT_BIN: /opt/venv/bin/tht
|
||||
THT_WORKSPACE_REGISTRY_ROOT: /data/workspace-registry
|
||||
THT_WORKSPACE_GIT_REMOTE: ${THT_WORKSPACE_GIT_REMOTE:-ssh://git@git.example.invalid/platform/thoth-workspaces.git}
|
||||
THT_WORKSPACE_GIT_BRANCH: ${THT_WORKSPACE_GIT_BRANCH:-main}
|
||||
THT_WORKSPACE_INSTALLATION_ID: ${THT_WORKSPACE_INSTALLATION_ID:-local-laptop}
|
||||
THT_WORKSPACE_GIT_AUTHOR_NAME: ${THT_WORKSPACE_GIT_AUTHOR_NAME:-Thoth Workspace Registry}
|
||||
THT_WORKSPACE_GIT_AUTHOR_EMAIL: ${THT_WORKSPACE_GIT_AUTHOR_EMAIL:-thoth-workspace-registry@localhost}
|
||||
THT_WORKSPACE_SECRET_ROOTS: /run/secrets
|
||||
GIT_CONFIG_COUNT: "2"
|
||||
GIT_CONFIG_KEY_0: credential.helper
|
||||
GIT_CONFIG_VALUE_0: store --file=/run/secrets/workspace-registry-git-credentials
|
||||
GIT_CONFIG_KEY_1: http.sslCAInfo
|
||||
GIT_CONFIG_VALUE_1: /run/secrets/workspace-registry-git-ca
|
||||
GIT_SSH_COMMAND: ssh -i /run/secrets/workspace-registry-git-ssh-key -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=/run/secrets/workspace-registry-git-known-hosts
|
||||
ports:
|
||||
- "127.0.0.1:8787:8787"
|
||||
volumes:
|
||||
- thoth-local-data:/data
|
||||
- workspace-registry:/data/workspace-registry
|
||||
- ${THT_WORKSPACE_GIT_CREDENTIALS_FILE:-./installation-secrets/git-credentials}:/run/secrets/workspace-registry-git-credentials:ro
|
||||
- ${THT_WORKSPACE_GIT_CA_FILE:-./installation-secrets/git-ca.pem}:/run/secrets/workspace-registry-git-ca:ro
|
||||
- ${THT_WORKSPACE_GIT_SSH_KEY_FILE:-./installation-secrets/git-ssh-key}:/run/secrets/workspace-registry-git-ssh-key:ro
|
||||
- ${THT_WORKSPACE_GIT_KNOWN_HOSTS_FILE:-./installation-secrets/git-known-hosts}:/run/secrets/workspace-registry-git-known-hosts:ro
|
||||
restart: "no"
|
||||
|
||||
volumes:
|
||||
thoth-local-data: {}
|
||||
workspace-registry: {}
|
||||
@@ -0,0 +1,47 @@
|
||||
# Server registry example. Copy to a reviewed, untracked operator directory and set host paths
|
||||
# and Git values in its .env. The core remains non-root (UID 10001) and never receives secrets
|
||||
# through the Git checkout.
|
||||
name: thothii-workspace-registry-server
|
||||
|
||||
services:
|
||||
core:
|
||||
image: thothii-core:local
|
||||
build:
|
||||
context: ../../..
|
||||
dockerfile: docker/core.Dockerfile
|
||||
environment:
|
||||
HOST: 0.0.0.0
|
||||
PORT: "8787"
|
||||
AUTH_MODE: upstream
|
||||
THOTH_PUBLIC_EXPOSURE: "true"
|
||||
THT_HARNESS_DIR: /app/harness
|
||||
THT_BIN: /opt/venv/bin/tht
|
||||
SETTINGS_FILE: /data/settings/settings.json
|
||||
THT_WORKSPACE_REGISTRY_ROOT: /data/workspace-registry
|
||||
THT_WORKSPACE_GIT_REMOTE: ${THT_WORKSPACE_GIT_REMOTE:-ssh://git@git.example.invalid/platform/thoth-workspaces.git}
|
||||
THT_WORKSPACE_GIT_BRANCH: ${THT_WORKSPACE_GIT_BRANCH:-main}
|
||||
THT_WORKSPACE_INSTALLATION_ID: ${THT_WORKSPACE_INSTALLATION_ID:-production-1}
|
||||
THT_WORKSPACE_GIT_AUTHOR_NAME: ${THT_WORKSPACE_GIT_AUTHOR_NAME:-Thoth Workspace Registry}
|
||||
THT_WORKSPACE_GIT_AUTHOR_EMAIL: ${THT_WORKSPACE_GIT_AUTHOR_EMAIL:-thoth-workspace-registry@localhost}
|
||||
THT_WORKSPACE_SECRET_ROOTS: /run/secrets
|
||||
GIT_CONFIG_COUNT: "2"
|
||||
GIT_CONFIG_KEY_0: credential.helper
|
||||
GIT_CONFIG_VALUE_0: store --file=/run/secrets/workspace-registry-git-credentials
|
||||
GIT_CONFIG_KEY_1: http.sslCAInfo
|
||||
GIT_CONFIG_VALUE_1: /run/secrets/workspace-registry-git-ca
|
||||
GIT_SSH_COMMAND: ssh -i /run/secrets/workspace-registry-git-ssh-key -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes -o UserKnownHostsFile=/run/secrets/workspace-registry-git-known-hosts
|
||||
volumes:
|
||||
- ${THT_HOST_DATA_ROOT:-/srv/thothii/data}:/data
|
||||
- ${THT_WORKSPACE_REGISTRY_HOST_PATH:-/srv/thothii/workspace-registry}:/data/workspace-registry
|
||||
- ${THT_WORKSPACE_GIT_CREDENTIALS_FILE:-/srv/thothii/secrets/git-credentials}:/run/secrets/workspace-registry-git-credentials:ro
|
||||
- ${THT_WORKSPACE_GIT_CA_FILE:-/srv/thothii/secrets/git-ca.pem}:/run/secrets/workspace-registry-git-ca:ro
|
||||
- ${THT_WORKSPACE_GIT_SSH_KEY_FILE:-/srv/thothii/secrets/git-ssh-key}:/run/secrets/workspace-registry-git-ssh-key:ro
|
||||
- ${THT_WORKSPACE_GIT_KNOWN_HOSTS_FILE:-/srv/thothii/secrets/git-known-hosts}:/run/secrets/workspace-registry-git-known-hosts:ro
|
||||
networks:
|
||||
- portal
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
portal:
|
||||
external: true
|
||||
name: ${THT_PORTAL_NETWORK:-omics_portal_omics_network}
|
||||
@@ -0,0 +1,185 @@
|
||||
# Local workspace-registry installation (Mac and PC)
|
||||
|
||||
This guide runs a single-user ThothII registry on Docker Desktop (macOS or Windows) or a local
|
||||
Linux Docker Engine. It is intentionally loopback-only. Git is shared; the checkout, connector
|
||||
bindings, credentials, and session data are local. Never put credentials in workspace YAML, Git,
|
||||
browser drafts, diagnostics, or `.env.example`.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- macOS: Docker Desktop, Git, and sufficient volume disk space. Git Credential Manager is useful
|
||||
for HTTPS sign-in.
|
||||
- Windows: Docker Desktop with WSL2, Git for Windows, and the clone enabled in Docker file sharing.
|
||||
Use absolute paths/WSL paths; PowerShell uses `;` rather than `:` in `COMPOSE_FILE`.
|
||||
- Linux PC: Docker Engine, Compose plugin, Git, and a user permitted to run Docker.
|
||||
- Outbound access to the Git remote. A local installation needs no inbound firewall rule.
|
||||
|
||||
Keep the operator `.env` and `installation-secrets/` outside the workspace-registry Git checkout.
|
||||
On macOS/Linux use mode `0600` for individual secret files. On Windows apply an ACL that grants
|
||||
read access only to the Docker Desktop user. Do not use an empty file to silently bypass a selected
|
||||
authentication method.
|
||||
|
||||
## Git remote: SSH and HTTPS
|
||||
|
||||
Create one private repository such as `thoth-workspaces.git`. It contains canonical workspace
|
||||
definitions and generated artifacts only:
|
||||
|
||||
```text
|
||||
thoth-workspaces.yaml
|
||||
workspaces/<workspace-id>.yaml
|
||||
workspaces/<workspace-id>.env.example
|
||||
workspaces/<workspace-id>.md
|
||||
```
|
||||
|
||||
For SSH, use a scoped deploy key, a verified `known_hosts` file, and strict host-key checking. For
|
||||
HTTPS, use Git Credential Manager or a secret-manager-created credentials file. Mount a private
|
||||
HTTPS CA as its own file. Do not disable host or certificate verification.
|
||||
|
||||
```dotenv
|
||||
THT_WORKSPACE_GIT_REMOTE=ssh://git@git.example.invalid/platform/thoth-workspaces.git
|
||||
THT_WORKSPACE_GIT_BRANCH=main
|
||||
THT_WORKSPACE_INSTALLATION_ID=local-laptop
|
||||
THT_WORKSPACE_GIT_SSH_KEY_FILE=/absolute/path/installation-secrets/git-ssh-key
|
||||
THT_WORKSPACE_GIT_KNOWN_HOSTS_FILE=/absolute/path/installation-secrets/git-known-hosts
|
||||
THT_WORKSPACE_GIT_CA_FILE=/absolute/path/installation-secrets/git-ca.pem
|
||||
```
|
||||
|
||||
For HTTPS set `THT_WORKSPACE_GIT_CREDENTIALS_FILE` instead of the SSH key/known-hosts pair. Remote
|
||||
and branch are non-secret; every `*_FILE` is a local path whose content never enters Git or logs.
|
||||
|
||||
## Shared Git values, local bindings, and secret files
|
||||
|
||||
| Location | Contains | Never contains |
|
||||
| --- | --- | --- |
|
||||
| Git workspace repository | schema v2 YAML, generated binding names, LLM policy, model/index identity | installation hostnames, keys, passwords, certificates, SSH keys |
|
||||
| local `.env` | remote, branch, installation ID, selected transport and endpoints | secret contents |
|
||||
| local secret directory | Git credentials/key, known hosts, CA, connector secret files | a copied registry checkout |
|
||||
| Docker volumes | registry checkout/snapshots/state/locks and local data | host-only secret source files |
|
||||
|
||||
The persistent volume is `/data/workspace-registry`:
|
||||
|
||||
```text
|
||||
repo/ # persistent Git checkout
|
||||
snapshots/ # immutable validated revisions used by sessions
|
||||
state/ # active revision and registry state
|
||||
locks/ # short-lived publish locks
|
||||
```
|
||||
|
||||
Installation variables are deterministic: `psd-clinical` becomes `PSD_CLINICAL`, and every name
|
||||
is `THT_WS_<NAMESPACE>_<ROLE>_<SUFFIX>`. Credentials and certificates use `*_FILE` path variables.
|
||||
If declared, `THT_WS_PSD_CLINICAL_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. Canonical YAML keeps database/schema/collection,
|
||||
distance, embedding model, and dimensions shared in Git.
|
||||
|
||||
```dotenv
|
||||
# Direct PostgreSQL and pgvector
|
||||
THT_WS_PSD_CLINICAL_DWH_TRANSPORT=postgres_direct
|
||||
THT_WS_PSD_CLINICAL_DWH_HOST=dwh.example.invalid
|
||||
THT_WS_PSD_CLINICAL_DWH_PORT=5432
|
||||
THT_WS_PSD_CLINICAL_DWH_USER=thoth_reader
|
||||
THT_WS_PSD_CLINICAL_DWH_PASSWORD_FILE=/run/secrets/psd-dwh-reader
|
||||
THT_WS_PSD_CLINICAL_VECTOR_TRANSPORT=pgvector_direct
|
||||
THT_WS_PSD_CLINICAL_VECTOR_HOST=vector.example.invalid
|
||||
THT_WS_PSD_CLINICAL_VECTOR_PORT=5432
|
||||
THT_WS_PSD_CLINICAL_VECTOR_USER=thoth_vector_reader
|
||||
THT_WS_PSD_CLINICAL_VECTOR_PASSWORD_FILE=/run/secrets/psd-vector-reader
|
||||
THT_WS_PSD_CLINICAL_EMBEDDING_BASE_URL=https://embeddings.example.invalid
|
||||
```
|
||||
|
||||
```dotenv
|
||||
# REST; an API-key file is needed only for a declared bearer/x-api-key diagnostic.
|
||||
THT_WS_PSD_CLINICAL_DWH_TRANSPORT=rest_api
|
||||
THT_WS_PSD_CLINICAL_DWH_BASE_URL=https://dwh.example.invalid
|
||||
THT_WS_PSD_CLINICAL_DWH_API_KEY_FILE=/run/secrets/psd-dwh-api-key
|
||||
THT_WS_PSD_CLINICAL_VECTOR_TRANSPORT=rest_api
|
||||
THT_WS_PSD_CLINICAL_VECTOR_BASE_URL=https://vectors.example.invalid
|
||||
THT_WS_PSD_CLINICAL_VECTOR_API_KEY_FILE=/run/secrets/psd-vector-api-key
|
||||
```
|
||||
|
||||
```dotenv
|
||||
# SSH tunnel; host-key verification and TLS target name remain mandatory.
|
||||
THT_WS_PSD_CLINICAL_DWH_TRANSPORT=ssh_tunnel
|
||||
THT_WS_PSD_CLINICAL_DWH_USER=thoth_reader
|
||||
THT_WS_PSD_CLINICAL_DWH_PASSWORD_FILE=/run/secrets/psd-dwh-reader
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_HOST=bastion.example.invalid
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_PORT=22
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_USER=thoth_tunnel
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_PRIVATE_KEY_FILE=/run/secrets/psd-dwh-tunnel-key
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_KNOWN_HOSTS_FILE=/run/secrets/psd-dwh-known-hosts
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_TARGET_HOST=dwh.internal.example
|
||||
THT_WS_PSD_CLINICAL_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
|
||||
[diagnostic protocol](../workspace-diagnostic-protocol.md).
|
||||
|
||||
## Bootstrap, first pull, and diagnostics
|
||||
|
||||
Copy [the local Compose example](examples/local-compose.workspace-registry.yaml) into an untracked
|
||||
operator directory, create its local `.env` and mounted secret files, then render it before start.
|
||||
|
||||
<!-- verify:command -->
|
||||
```sh
|
||||
docker compose -f docs/install/examples/local-compose.workspace-registry.yaml config --quiet
|
||||
```
|
||||
|
||||
From the operator directory:
|
||||
|
||||
```sh
|
||||
docker compose -f compose.workspace-registry.yaml up --build -d
|
||||
curl --fail --silent http://127.0.0.1:8787/health
|
||||
curl --fail --silent http://127.0.0.1:8787/workspace-registry/status
|
||||
curl --fail --silent http://127.0.0.1:8787/workspaces
|
||||
```
|
||||
|
||||
The first status request clones, validates all descriptors, and atomically activates a snapshot.
|
||||
Use `POST /workspace-registry/pull` to fetch later revisions. Run workspace diagnostics only after
|
||||
required bindings are mounted. The optional writer probe uses a distinct writer file and removes
|
||||
its uniquely named temporary record; ordinary diagnostics are read-only.
|
||||
|
||||
To migrate an existing PSD descriptor, create/clone an empty private remote, transform with
|
||||
absolute paths, review the schema-v1 result, explicitly add vector database/schema and the complete
|
||||
schema-v2 contract, then commit/push. The transformer never imports `${ENV}` values or secrets.
|
||||
|
||||
```sh
|
||||
npm --prefix backend run build
|
||||
node backend/dist/workspaces/migrate-legacy.js --input /absolute/path/psd.yaml --output /absolute/path/thoth-workspaces
|
||||
```
|
||||
|
||||
## Publish, update, backup, outage recovery, and rollback
|
||||
|
||||
Drafts live only in browser storage. Review the canonical field diff, validate/test locally, then
|
||||
publish. If conflicted, pull first and create a new reviewed field-level draft; never hand-edit the
|
||||
running `repo/` volume. Before upgrading, record registry status, stop Compose, and take a
|
||||
timestamped ownership-preserving backup of both registry and local data volumes while excluding
|
||||
`installation-secrets/`. Render Compose, rebuild, start, and check status before resuming work.
|
||||
|
||||
After a valid bootstrap, remote outage retains the last valid snapshot and reports `degraded: true`.
|
||||
Pinned sessions continue. Repair network/authentication, pull, and confirm non-degraded status. To
|
||||
undo a bad remote change, create a reviewed Git revert/release branch, advance the remote through
|
||||
normal policy, pull, and confirm its new snapshot. Do not delete `snapshots/` as rollback.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Stable code | Meaning and safe action |
|
||||
| --- | --- |
|
||||
| `workspace_invalid` | Invalid descriptor/path/snapshot; restore a reviewed canonical revision. |
|
||||
| `binding_missing` | A selected value or readable `*_FILE` is absent; fix the local binding/mount. |
|
||||
| `workspace_not_activatable` | Diagnostics cannot activate the workspace; correct the selected transport. |
|
||||
| `workspace_stale` | Checkout changed or is busy; stop competing pull/publish work. |
|
||||
| `workspace_conflict` | Draft base differs from Git; pull, resolve the diff, validate, republish. |
|
||||
| `git_unavailable` | Remote, path, network, or lock unavailable; preserve the degraded valid snapshot. |
|
||||
| `git_auth_failed` | Mounted SSH/HTTPS material rejected/unreadable; rotate or fix permissions without logging it. |
|
||||
| `git_non_fast_forward` | Checkout diverged; reconcile through the registry workflow. |
|
||||
| `git_push_rejected` | Remote policy rejected the change; review branch protection/hooks. |
|
||||
| `connector_unavailable` | DNS/TLS/auth/resource identity diagnostic failed; inspect local bindings and egress. |
|
||||
| `semantic_index_incompatible` | Collection/model/dimensions/distance differs from Git; perform an explicit index migration. |
|
||||
|
||||
On macOS, restart Docker Desktop if a named volume disappears. On Windows, check WSL2 and Docker
|
||||
file sharing. A failed first bootstrap has no snapshot fallback: repair remote trust and retry;
|
||||
never create an unreviewed local registry repository.
|
||||
@@ -0,0 +1,195 @@
|
||||
# Server workspace-registry installation
|
||||
|
||||
This is the production operator guide. The application image is read-only, secrets are mounted
|
||||
read-only, and sessions use immutable Git-validated snapshots. Expose the application only behind
|
||||
an authenticated same-origin reverse proxy; never publish the core port directly.
|
||||
|
||||
## Service account, storage, and firewall
|
||||
|
||||
Create a dedicated host service account and an operator root such as `/srv/thothii`. The core
|
||||
container is non-root UID/GID `10001` (`thoth`), so give that identity read/write ownership before
|
||||
first startup. Keep storage separated:
|
||||
|
||||
```text
|
||||
/srv/thothii/data/ # settings, session data, Pi state as applicable
|
||||
/srv/thothii/workspace-registry/ # repo/, snapshots/, state/, locks/
|
||||
/srv/thothii/secrets/ # Git and connector secret files, mode 0700
|
||||
/srv/thothii/operator/ # untracked Compose/.env, mode 0700
|
||||
```
|
||||
|
||||
Permit outbound TCP only to approved Git/Gitea, DWH, vector, embedding, and bastion endpoints.
|
||||
Allow inbound traffic only from the reverse proxy/Docker network. Do not give the runtime service
|
||||
account Gitea administration, database-superuser rights, or a shell in the Git host.
|
||||
|
||||
## Gitea and remote Git setup
|
||||
|
||||
Create a private Gitea (or compatible Git) repository such as `platform/thoth-workspaces`. Protect
|
||||
`main` according to the release policy and grant the ThothII publisher only the intended repository
|
||||
scope. Commit canonical schema-v2 descriptors and generated `.md`/`.env.example` artifacts only;
|
||||
do not commit installation bindings or secret material.
|
||||
|
||||
For SSH, create a least-privilege deploy key, record Gitea's host key in managed known-hosts, and
|
||||
use `ssh://git@git.example.invalid/platform/thoth-workspaces.git`. For HTTPS, create a scoped
|
||||
machine credential in the secret manager and mount the Gitea/private CA separately. Never use a
|
||||
Gitea admin credential in the application.
|
||||
|
||||
Bootstrap an empty remote from a temporary review clone: migrate legacy descriptors, review their
|
||||
schema-v2 identity and generated artifacts, commit, and push `main`. The running server is not an
|
||||
authoring environment for migration.
|
||||
|
||||
## Git credentials, CA, SSH key, and known-hosts mounts
|
||||
|
||||
Use the secret manager or a protected host-only procedure to create independent regular files under
|
||||
`/srv/thothii/secrets`. Set individual mode `0600`, directory mode `0700`, and ownership readable
|
||||
by the service account. These path-only variables are mounted read-only by Compose:
|
||||
|
||||
```dotenv
|
||||
THT_WORKSPACE_GIT_CREDENTIALS_FILE=/srv/thothii/secrets/git-credentials
|
||||
THT_WORKSPACE_GIT_CA_FILE=/srv/thothii/secrets/git-ca.pem
|
||||
THT_WORKSPACE_GIT_SSH_KEY_FILE=/srv/thothii/secrets/git-ssh-key
|
||||
THT_WORKSPACE_GIT_KNOWN_HOSTS_FILE=/srv/thothii/secrets/git-known-hosts
|
||||
```
|
||||
|
||||
Use the credential file for HTTPS, or key and known-hosts for SSH. Strict host-key checking stays
|
||||
enabled and Git stderr is not exposed by the API. Rotate by atomically replacing the secret file,
|
||||
restarting `core`, and performing pull/status; never put the material in an environment variable or
|
||||
`docker compose config` output.
|
||||
|
||||
## Shared Git values, local bindings, and secret files
|
||||
|
||||
Git describes workspace schema, immutable ID, DWH/vector identity, semantic-index dimensions and
|
||||
distance, embedding contract, and LLM policy. The installation supplies remote/branch/installation
|
||||
ID, transport, endpoints, users, ports, and `THT_WS_*` bindings. Secret contents are only in files,
|
||||
never the values stored in Git or browser-local drafts.
|
||||
|
||||
The runtime registry layout is persistent and must be backed up together:
|
||||
|
||||
```text
|
||||
/data/workspace-registry/repo/
|
||||
/data/workspace-registry/snapshots/
|
||||
/data/workspace-registry/state/
|
||||
/data/workspace-registry/locks/
|
||||
```
|
||||
|
||||
Variable names derive from the immutable ID: `psd-clinical` becomes `PSD_CLINICAL`, producing
|
||||
`THT_WS_PSD_CLINICAL_DWH_PASSWORD_FILE`. A declared vector writer uses the distinct
|
||||
`THT_WS_PSD_CLINICAL_VECTOR_WRITER_API_KEY_FILE`; a reader file is never a writer substitute.
|
||||
|
||||
## Direct PostgreSQL, REST, and SSH tunnel bindings
|
||||
|
||||
Select only a transport allowed by canonical YAML; preserve database/schema/collection, model,
|
||||
dimensions, and distance as Git-shared identity.
|
||||
|
||||
```dotenv
|
||||
# Direct PostgreSQL/pgvector with verified native TLS if a CA path is supplied.
|
||||
THT_WS_PSD_CLINICAL_DWH_TRANSPORT=postgres_direct
|
||||
THT_WS_PSD_CLINICAL_DWH_HOST=dwh.internal.example
|
||||
THT_WS_PSD_CLINICAL_DWH_PORT=5432
|
||||
THT_WS_PSD_CLINICAL_DWH_USER=thoth_reader
|
||||
THT_WS_PSD_CLINICAL_DWH_PASSWORD_FILE=/run/secrets/psd-dwh-reader
|
||||
THT_WS_PSD_CLINICAL_VECTOR_TRANSPORT=pgvector_direct
|
||||
THT_WS_PSD_CLINICAL_VECTOR_HOST=vector.internal.example
|
||||
THT_WS_PSD_CLINICAL_VECTOR_PORT=5432
|
||||
THT_WS_PSD_CLINICAL_VECTOR_USER=thoth_vector_reader
|
||||
THT_WS_PSD_CLINICAL_VECTOR_PASSWORD_FILE=/run/secrets/psd-vector-reader
|
||||
```
|
||||
|
||||
```dotenv
|
||||
# REST needs API-key file paths only when the descriptor declares authenticated diagnostics.
|
||||
THT_WS_PSD_CLINICAL_DWH_TRANSPORT=rest_api
|
||||
THT_WS_PSD_CLINICAL_DWH_BASE_URL=https://dwh.internal.example
|
||||
THT_WS_PSD_CLINICAL_DWH_API_KEY_FILE=/run/secrets/psd-dwh-api-key
|
||||
THT_WS_PSD_CLINICAL_VECTOR_TRANSPORT=rest_api
|
||||
THT_WS_PSD_CLINICAL_VECTOR_BASE_URL=https://vectors.internal.example
|
||||
THT_WS_PSD_CLINICAL_VECTOR_API_KEY_FILE=/run/secrets/psd-vector-api-key
|
||||
THT_WS_PSD_CLINICAL_EMBEDDING_BASE_URL=https://embeddings.internal.example
|
||||
```
|
||||
|
||||
```dotenv
|
||||
# SSH tunnel requires explicit host-key verification and TLS target identity.
|
||||
THT_WS_PSD_CLINICAL_DWH_TRANSPORT=ssh_tunnel
|
||||
THT_WS_PSD_CLINICAL_DWH_USER=thoth_reader
|
||||
THT_WS_PSD_CLINICAL_DWH_PASSWORD_FILE=/run/secrets/psd-dwh-reader
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_HOST=bastion.internal.example
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_PORT=22
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_USER=thoth_tunnel
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_PRIVATE_KEY_FILE=/run/secrets/psd-dwh-tunnel-key
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_KNOWN_HOSTS_FILE=/run/secrets/psd-dwh-known-hosts
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_TARGET_HOST=dwh.internal.example
|
||||
THT_WS_PSD_CLINICAL_DWH_SSH_TARGET_PORT=5432
|
||||
```
|
||||
|
||||
Repeat SSH variables for `VECTOR` when selected. 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.
|
||||
|
||||
## Same-origin reverse proxy, bootstrap, and health
|
||||
|
||||
Copy [the server Compose example](examples/server-compose.workspace-registry.yaml) to the protected
|
||||
operator directory, set host paths/remote/branch/installation ID/portal network in local `.env`,
|
||||
then render it before deployment.
|
||||
|
||||
<!-- verify:command -->
|
||||
```sh
|
||||
docker compose -f docs/install/examples/server-compose.workspace-registry.yaml config --quiet
|
||||
```
|
||||
|
||||
Configure the portal proxy so the frontend and `/api` share one origin. It authenticates first and
|
||||
forwards the trusted identity expected by `AUTH_MODE=upstream`; it is the only public listener.
|
||||
From a trusted maintenance shell:
|
||||
|
||||
```sh
|
||||
docker compose -f compose.workspace-registry.yaml up --build -d
|
||||
docker compose -f compose.workspace-registry.yaml exec -T core curl --fail --silent http://127.0.0.1:8787/health
|
||||
docker compose -f compose.workspace-registry.yaml exec -T core curl --fail --silent http://127.0.0.1:8787/workspace-registry/status
|
||||
```
|
||||
|
||||
`/health` is liveness. Registry status verifies branch/head/degraded state and the active validated
|
||||
snapshot; authenticated `/workspaces` verifies application access. A server with no active snapshot
|
||||
is not ready for workspace sessions even if liveness succeeds.
|
||||
|
||||
## Pull, publish, upgrade, backup, and recovery
|
||||
|
||||
Use the authenticated Workspace Management UI or `POST /workspace-registry/pull`. Drafts are
|
||||
browser-local. Publish takes a canonical diff, validates before commit, and pushes under a registry
|
||||
lock. On `workspace_conflict`, pull, resolve the reviewed field-level draft, validate/test, and
|
||||
publish; never edit `repo/` inside a running volume.
|
||||
|
||||
For upgrades, record active status/head, drain active Pi work, stop `core`, and take a
|
||||
filesystem-consistent backup of `/srv/thothii/workspace-registry` plus `/srv/thothii/data`. Exclude
|
||||
`/srv/thothii/secrets`. Render Compose, deploy the compatible image, verify health/status, then
|
||||
resume proxy traffic.
|
||||
|
||||
For PSD migration, use a temporary review clone and the legacy transformer with absolute paths.
|
||||
Its schema-v1 output is `migration_required`; explicitly supply vector database/schema, collection
|
||||
identity, diagnostics, and the reviewed v2 contract before commit. Never import `${ENV}` values or
|
||||
copy secret files.
|
||||
|
||||
After valid bootstrap, Git outage retains the active snapshot with `degraded: true`. Repair
|
||||
egress/DNS/CA/credentials, pull, and confirm healthy status. Roll back a bad descriptor through a
|
||||
reviewed Git revert/release branch, advance the remote through normal policy, pull it, and confirm
|
||||
the replacement snapshot. Restore a registry backup only while stopped and with a compatible image;
|
||||
do not delete snapshots as a rollback shortcut.
|
||||
|
||||
## Troubleshooting and snapshot rollback
|
||||
|
||||
| Stable code | Meaning and safe response |
|
||||
| --- | --- |
|
||||
| `workspace_invalid` | Invalid descriptor/path/snapshot; restore a reviewed canonical Git revision. |
|
||||
| `binding_missing` | Missing/invalid local value or readable `*_FILE`; correct mount and permissions. |
|
||||
| `workspace_not_activatable` | Bindings/diagnostics cannot activate; use sanitized fields to fix selected transport. |
|
||||
| `workspace_stale` | Checkout changed/locked; stop concurrent registry work, never force Git in the volume. |
|
||||
| `workspace_conflict` | Draft base stale; pull, resolve, validate, republish. |
|
||||
| `git_unavailable` | Storage/remote/DNS/firewall/lock failed; preserve degraded active state while repairing it. |
|
||||
| `git_auth_failed` | SSH/HTTPS material rejected or unreadable; rotate/fix file without printing it. |
|
||||
| `git_non_fast_forward` | Checkout diverged; reconcile through registry workflow and branch policy. |
|
||||
| `git_push_rejected` | Gitea policy rejected publish; review hooks/branch protection. |
|
||||
| `connector_unavailable` | DNS/TLS/auth/resource identity failed; check egress and local bindings. |
|
||||
| `semantic_index_incompatible` | Collection/model/dimensions/distance differs; perform explicit index migration. |
|
||||
|
||||
If the current snapshot is valid but Git remains down, continue only work safe on that pinned
|
||||
revision and monitor status. If snapshots are missing or corrupt, stop the service, restore the
|
||||
newest verified registry backup, start it privately, verify status, and then reopen proxy traffic.
|
||||
A first-bootstrap failure has no fallback: repair remote trust rather than creating an unreviewed
|
||||
runtime checkout.
|
||||
Reference in New Issue
Block a user