# Installing Toad Toad is a rootless deployment controller, not a self-installing privileged daemon. Its distributable host assets live in [`deploy/`](deploy/): - `toad.container`: control plane; - `toad-ingress.container`: HTTP ingress gateway; - `toad.network`: private application network; - `gateway.Caddyfile`: fail-closed gateway configuration; - `setup-user.sh` and `start.sh`: the current host integration reference. ## Host contract An administrator must provide: 1. a dedicated `toad` account with a lingering systemd user manager and rootless Podman socket; 2. `/data/toad`, owned only by that account; 3. a shared ingress directory, writable by `toad` and connectable by the public reverse-proxy identity; 4. persistent `container_file_t` labeling for the gateway configuration and ingress directory when SELinux is enforcing; 5. an operator-owned enrollment file and ingress environment; 6. a public reverse-proxy mount and route to the gateway socket. These decisions cannot be encoded safely by a per-user Quadlet because they cross host users and security domains. An OS package may later encode account and directory creation through `systemd-sysusers` and `systemd-tmpfiles`. ## Required files Install the three Quadlets under the `toad` user's Quadlet directory. Install these operator-owned files: ```text /data/toad/enrollment.json /data/toad/gateway.Caddyfile /data/toad/ingress.env /data/toad/nugu.css ``` `enrollment.json` may initially contain `[]`. `nugu.css` is the optional dashboard palette selected with `TOAD_THEME_CSS=/data/toad/nugu.css`; Toad has a built-in fallback palette. `ingress.env` supplies the hostname accepted by the bundled gateway: ```text TOAD_WEB_HOST=toad.example.net ``` The gateway listens only on `/data/toad-ingress/http.sock`, creates no host TCP listener, and returns 404 for unknown hosts. The public reverse proxy mounts only `/data/toad-ingress`; it must never mount `/data/toad`, the Podman socket, the systemd user bus, or Toad's administrative socket. ## Public Caddy handoff The outer proxy terminates TLS and authentication, then forwards the original Host header over the shared socket: ```caddyfile toad.example.net { basic_auth { admin } reverse_proxy unix//run/toad-ingress/http.sock } ``` Mount `/data/toad-ingress` into that proxy at `/run/toad-ingress` read-only. A read-only bind mount still permits connecting to a Unix socket; filesystem permissions and SELinux remain the security boundary. The dashboard reports deployment state, live readiness, sanitized enrollment fields, container state, systemd user-unit properties, and Toad-owned operation logs. It deliberately does not expose raw Quadlets, environment values, host journal entries, or generic host metrics. ## Operator CLI Run the CLI inside the control-plane container through the service user's Podman scope. The reference installer places a root-only `/usr/local/bin/toad` wrapper on the host. No token is needed over the local Unix administration socket. Remote TCP consumers require a service-scoped token issued with `toad token issue`. `toad deploy ` accepts only a manifest digest formatted `sha256:<64 lowercase hex>`. The enrolled service supplies its image repository, so pass Luci's successful `digest` field, not its `reference` field. Luci publication evidence does not invoke Toad or provide Toad credentials.