# Manual standalone installation [Versione italiana](standalone-manual-it.md) This is the verification procedure for preparing THothII as a standalone application in `full` mode on macOS, Windows, and Linux. In this document, “standalone” means that the user does not need to install Node.js, Python or Pi on the host: the application services and local semantic services run through Docker. DWH and LLM providers remain external endpoints configured by the installation; this is not an offline package. This path uses no graphical installer, native launcher, or Docker Hub image. It starts from a Gitea clone and uses explicit terminal commands. Publishing pre-built images is a later step. ## Verification matrix | System | Recommended terminal | Runtime | Test architecture | | --- | --- | --- | --- | | macOS supported by the installed Docker Desktop version | Bash in Terminal | Docker Desktop | Apple Silicon (`arm64`) | | Windows 11 | Ubuntu inside WSL2 | Docker Desktop with WSL2 integration | x64 (`amd64`) | | Ubuntu Linux 22.04 or 24.04 | Bash | Docker Engine + Compose v2 | x64 (`amd64`) | Intel macOS is excluded from the first verification campaign. ARM Linux may be tested when the machine’s Docker runtime reports `arm64`, but it is not part of the minimum matrix. Documentation and Mac prerequisite checks have passed. Complete fresh installations on all three systems remain pending; this matrix describes the tests to perform, not completed certification. ## Before you start You need: - access to the THothII Gitea repository and the workspace Git repository; - Git; - Docker Desktop on macOS and Windows, or Docker Engine with the Compose v2 plugin on Linux; - Bash, `curl`, OpenSSL and `shasum` (Ubuntu package: `libdigest-sha-perl`); - enough disk space to build the images and download the embedding model; - the DWH and LLM endpoints, plus the credentials required by the installation. On Linux, the current user must be able to run Docker. If the system requires `sudo`, add the user to the Docker group according to local policy and open a new session before continuing. On Windows, run every command in this guide from Ubuntu under WSL2. In Docker Desktop, enable WSL2 integration for that distribution. Clone the project inside the WSL2 Linux filesystem, for example under `~/src`, rather than under `/mnt/c`: this avoids slow builds and path/line-ending issues. Pi does not need to be installed on the host. Check the runtime before or immediately after cloning: ```sh docker version docker compose version docker version --format '{{.Server.Arch}}' ``` The last command must return `amd64`, `x86_64`, `arm64`, or `aarch64`. ## 1. Clone a project revision Use the project repository on Gitea: ```sh mkdir -p "$HOME/src" cd "$HOME/src" git clone https://git.tylconsulting.it/mptyl/ThothII.git cd ThothII git rev-parse --short HEAD ``` For an SSH clone, when the key is already authorized on Gitea: ```sh git clone git@git.tylconsulting.it:mptyl/ThothII.git ``` Record the hash printed by `git rev-parse` for a repeatable test. In a later campaign, use the maintainer-approved revision/tag rather than implicitly following a mutable `main` branch. ## 2. Check prerequisites and install the operator command From the clone root: ```sh bash scripts/check-standalone-prerequisites.sh export PATH="$HOME/.local/bin:$PATH" THT_INSTALL_DIRECTORY="$HOME/.local/bin" bash scripts/install-tht.sh tht version ``` `install-tht.sh` bootstraps only the native `tht` operator command; it does not install a desktop version of THothII. It uses the repository’s Docker builder, installs the binary for the current terminal environment, and installs it in the user directory. Persist `$HOME/.local/bin` in your shell PATH for new terminals too. An existing `tht` in this directory will be updated. On Windows, run these commands inside WSL2. The installed `tht` binary is the Linux binary inside WSL2; the application runtime remains Docker Desktop. Do not use `scripts/install-tht.ps1` as the primary path for this test. ## 3. Configure and start the local installation Run the remaining blocks in one Bash session from the physical clone root (`pwd -P`). First create two distinct catalog passwords, preserving any existing files: ```bash umask 077 mkdir -p deploy/local/secrets for name in catalog-runtime-password catalog-migrator-password; do target="deploy/local/secrets/$name" if [ ! -e "$target" ]; then (set -C; openssl rand -hex 32 > "$target") || exit 1 fi done export THT_CATALOG_RUNTIME_PASSWORD_SOURCE="$(pwd -P)/deploy/local/secrets/catalog-runtime-password" export THT_CATALOG_MIGRATOR_PASSWORD_SOURCE="$(pwd -P)/deploy/local/secrets/catalog-migrator-password" ``` Do not regenerate passwords for an initialized catalog. Configure without starting services: ```sh tht setup --profile local --shell-mode full --shell-default-locale en --configure-only ``` Answer the prompts as follows: | Prompt | Value or rule | | --- | --- | | Installation ID | `local`, unless one clone hosts multiple installations | | Deployment profile | `local` | | DWH API endpoint | An `http(s)` URL without user, password, query, or fragment; may be empty for a smoke-only test | | LLM API endpoint | An `http(s)` URL without credentials; may be empty for a smoke-only test | | Workspace repository URL | The workspace repository URL, not the THothII source clone | | Workspace branch | Normally `main` | | Workspace access | `ssh` with a deploy key, or `https` with a protected credential file | | File paths | Accept the default paths under `deploy/local/secrets/` for the first test | | Secret templates | Answer `yes` when protected files do not exist yet | | Authentication | Configure the local login required by the installation; never put passwords on a command line | The generated configuration is local and ignored by Git: ```text deploy/local/thothii-installation.yaml deploy/local/operator.env deploy/local/auth/ deploy/local/secrets/ ``` Edit secrets only in protected local files; never commit them. `deploy/env/local.env.example` is a tracked reference; the generated path `deploy/local/operator.env` is the active path for this installation. ### Complete protected files If setup created blank templates, enter the values with a local editor: ```sh chmod 600 deploy/local/secrets/* "${EDITOR:-vi}" deploy/local/secrets/thothii.secrets ``` The bundle must contain only `KEY=VALUE` lines for credentials actually used by `modelCatalog`. The allowed names and credential boundary are documented in the local file `deploy/secrets/README.md`. Do not put tokens in URLs, the YAML descriptor, the Git repository, or commands copied into the shell. For SSH workspace access, also provide the private key and `known_hosts` file requested by setup. For HTTPS access, provide the Git credential file and any required CA. Both must remain protected and outside version control. Before starting, complete these additional configuration steps: 1. Add `THT_CATALOG_RUNTIME_PASSWORD_SOURCE` and `THT_CATALOG_MIGRATOR_PASSWORD_SOURCE` to `deploy/local/operator.env`, with the same absolute paths exported above. Setup does not persist these two variables. Store paths, not passwords. 2. Replace the descriptor's generic `modelCatalog` with the approved provider/model configuration. The generated defaults do not replicate the existing Mac. See [Pi/model configuration](../general/pi-configuration.md) and the local example `deploy/psd/thothii-installation.yaml.example`. 3. Populate the keys referenced by `authentication.apiKeyEnv` in `thothii.secrets`. Providers using `pi_auth` need valid credentials at `PI_AUTH_FILE`; the `{}` template is not authentication. 4. Complete the workspace Git files. SSH requires an authorized deploy key and verified known-hosts; HTTPS requires the credential file and CA bundle expected by the overlay. Blank templates cannot provide repository access. After editing generated configuration, do not rerun setup: it rejects different existing content. Generate the projections and run the explicit migration below. Use `THT_GIT_ACCESS=https` if that was selected during setup. This block targets the fresh `local` descriptor with only the Git overlay; custom installations must include their extra descriptor overlays in the same order. ```bash INSTALLATION="$(pwd -P)/deploy/local/thothii-installation.yaml" tht --installation "$INSTALLATION" installation generate THT_PROJECT="thothii-$(printf '%s' "$INSTALLATION" | shasum -a 256 | cut -c 1-12)" THT_GIT_ACCESS=ssh compose=( docker compose --project-name "$THT_PROJECT" --project-directory "$(pwd -P)" --env-file "$(pwd -P)/deploy/local/operator.env" -f compose.yaml -f deploy/compose.local.yaml -f "deploy/compose.git-$THT_GIT_ACCESS.yaml" -f deploy/local/generated/compose.models.yaml ) "${compose[@]}" config --quiet "${compose[@]}" build core frontend "${compose[@]}" up -d catalog-db "${compose[@]}" run --rm catalog-migrate tht --installation "$INSTALLATION" start ``` Stop if a command fails. The project name matches the hash used by `tht`, preserving volume identity. `catalog-migrate` applies Catalog and Memory migrations; `tht start` does not run it automatically. Initial embedding-model download may take time. Use this installation-specific sequence, not `run-stack.sh` with a different environment/project name. ## 4. Verify the installation The descriptor generated for the default ID is: ```sh INSTALLATION="$(pwd -P)/deploy/local/thothii-installation.yaml" test -f "$INSTALLATION" bash scripts/verify-standalone-install.sh "$INSTALLATION" ``` The verifier is read-only: it runs `tht doctor --json` and `tht status` without restarting the stack, regenerating configuration, or printing secret contents. ### Gate A — platform smoke test on all three computers Record the following for each machine: ```sh uname -a docker version --format '{{.Server.Version}} {{.Server.Arch}}' tht version bash scripts/check-standalone-prerequisites.sh bash scripts/verify-standalone-install.sh "$INSTALLATION" ``` The gate passes when the clone is intact, Docker and Compose are reachable, `tht doctor` is OK, the stack is running, and the frontend responds at the default local URL `http://127.0.0.1:8080`. Doctor also checks workspace and Pi: record their failures separately rather than labeling every failure as a platform problem. Check HTTP readiness with: ```sh curl --fail --silent --show-error http://127.0.0.1:8080/health ``` ### Gate B — functional verification Run this on at least one machine with available endpoints and credentials: First follow [Workspace operations](../operations/workspaces.md) to import/prepare the workspace and configure the Database and local binding. The source clone does not transfer catalog data, secrets or sessions from the Mac. Connect any VPN required by DWH/model endpoints and verify that their names are reachable from containers too. 1. open `http://127.0.0.1:8080`; 2. sign in with the configured local account; 3. verify that the configured workspace is readable; 4. start a real question and complete the review gates through final SQL; 5. stop and restart the installation, then run `verify-standalone-install.sh` again. A Gate B failure involving DWH, the LLM provider, workspace Git, or credentials does not by itself prove a Docker portability problem: record the failed endpoint or component separately. ## Daily lifecycle Use the explicit descriptor when more than one installation may be discoverable: ```sh INSTALLATION="$PWD/deploy/local/thothii-installation.yaml" tht --installation "$INSTALLATION" status tht --installation "$INSTALLATION" start tht --installation "$INSTALLATION" start --build tht --installation "$INSTALLATION" logs tht --installation "$INSTALLATION" doctor --json tht --installation "$INSTALLATION" stop ``` Use `start --build` after source changes or to rebuild images from the current checkout. `stop` preserves volumes, sessions, the catalog, Pi state, Qdrant data, and the embedding model. Do not use `docker compose down --volumes` during a normal test: it is destructive and removes local data. For upgrades requiring migrations, follow the release runbook before starting the new application. ## Quick diagnosis | Symptom | Check | | --- | --- | | `Docker Engine is not reachable` | start Docker Desktop or the Docker service and rerun `docker info` | | Windows sees Docker but Bash fails | run the guide inside Ubuntu WSL2 and enable that distribution in Docker Desktop | | `tht: command not found` | open a new shell and check `command -v tht`; rerun the bootstrap if needed | | line-ending or executable-script errors | use a clone in the WSL2/Linux filesystem and rerun `bash scripts/...` | | unsupported architecture | check `docker version --format '{{.Server.Arch}}'`; the test requires `amd64` or `arm64` | | missing descriptor or env file | use `deploy/local/...` generated by `tht setup`, not an arbitrary copied file | | healthy stack but workflow failure | check external URLs, the credential bundle, workspace Git, and authentication separately | | data appears missing | check that `down --volumes` was not used; `stop` does not remove volumes | ## Acceptance checklist - [ ] The clone comes from the expected Gitea repository and the revision is recorded. - [ ] Docker Desktop/Engine and Compose v2 are available. - [ ] The runtime reports an allowed architecture. - [ ] `tht` was built from the repository and responds to `tht version`. - [ ] Setup uses `profile: local`, `shell.mode: full`, and `shell.defaultLocale: en`. - [ ] The descriptor, `operator.env`, authentication, and secrets exist only under `deploy/local/`. - [ ] No secret appears in Git, URLs, public YAML, or recorded commands. - [ ] Gate A passes on Apple Silicon macOS, x64 Windows WSL2, and x64 Linux. - [ ] Gate B runs on at least one machine with DWH and LLM available. - [ ] Stop/start and final verification complete without deleting volumes. ## Out of scope for this release The following remain future work: - publishing pre-built images on Docker Hub; - reducing prompts through a dedicated non-interactive configuration; - creating DMG, MSI/EXE, AppImage, or other native installers; - providing an offline runtime or bundling a local DWH/LLM into the application. ## Related documents - [Install and first start](first-start.md) - [Shell and localization](shell-and-language.md) - [Workspace operations](../operations/workspaces.md) - `deploy/secrets/README.md` (runtime secrets)