diff --git a/docs/superpowers/specs/2026-04-13-install-script-design.md b/docs/superpowers/specs/2026-04-13-install-script-design.md index 7a36c06..97c0ea1 100644 --- a/docs/superpowers/specs/2026-04-13-install-script-design.md +++ b/docs/superpowers/specs/2026-04-13-install-script-design.md @@ -14,7 +14,7 @@ The current architecture uses 7 services with 10+ bind-mounted config files. Thi | Image | Base | Bakes in | |---|---|---| -| `cameleer-traefik` | `traefik:v3` | Static/dynamic Traefik config, cert generation entrypoint (`openssl`), self-signed cert logic | +| `cameleer-traefik` | `traefik:v3` | Static/dynamic Traefik config (uses Traefik env var substitution for dynamic values like ports), cert generation entrypoint (`openssl`), self-signed cert logic | | `cameleer-postgres` | `postgres:16-alpine` | `init-databases.sh` (creates `cameleer_saas`, `logto` databases) | | `cameleer-clickhouse` | `clickhouse/clickhouse-server` | Init SQL (`CREATE DATABASE cameleer`), `clickhouse-users.xml`, `clickhouse-config.xml` (Prometheus metrics) | | `cameleer-logto` | `ghcr.io/logto-io/logto` | Custom sign-in UI, bootstrap logic (app/user/role/scope creation), vendor seed (env-var gated). Replaces the separate `logto-bootstrap` init container. | @@ -69,7 +69,7 @@ Both implement identical logic and produce identical output. They share a config The installer checks (does not install) these prerequisites: -- Docker Engine (Linux) or Docker Desktop (Windows) — minimum version TBD +- Docker Engine 24+ (Linux) or Docker Desktop 4.25+ (Windows) - Docker Compose v2 (`docker compose` subcommand) - `openssl` (Linux, for password generation) — PowerShell uses `[System.Security.Cryptography.RandomNumberGenerator]` - Ports 80, 443, 3002 are free (or custom ports if specified) @@ -411,3 +411,34 @@ main() ``` Each function has a direct equivalent in both bash and PowerShell. The logic, prompts, and output are identical across platforms. + +## TLS Certificate Flow (Simplified) + +With the `traefik-certs` init container merged into `cameleer-traefik`, the certificate flow works as follows: + +**Shared `certs` Docker volume** remains the mechanism for sharing TLS state between `cameleer-traefik` and `cameleer-saas` (which mounts it read-only for per-tenant server provisioning). + +**Self-signed mode (default):** +1. `cameleer-traefik` entrypoint checks if `/certs/cert.pem` exists in the volume +2. If not, generates a self-signed cert for `${PUBLIC_HOST}` with wildcard SAN using `openssl` +3. Writes `cert.pem`, `key.pem`, `meta.json` to the `certs` volume +4. Starts Traefik normally + +**Custom cert mode:** +1. The installer copies user-supplied cert files to `./cameleer/certs/` on the host +2. The generated `docker-compose.yml` bind-mounts `./certs/:/user-certs:ro` on the `cameleer-traefik` service +3. `cameleer-traefik` entrypoint detects `CERT_FILE=/user-certs/cert.pem` and `KEY_FILE=/user-certs/key.pem` +4. Validates and copies them to the shared `certs` Docker volume +5. Writes `meta.json` with certificate metadata +6. Starts Traefik normally + +**Runtime cert replacement** (via vendor UI) continues to work unchanged — `cameleer-saas` writes to the `certs` volume's `staged/` directory and performs atomic swaps. + +## Docker Socket Path + +The generated `docker-compose.yml` uses the platform-appropriate Docker socket path: + +- Linux: `/var/run/docker.sock:/var/run/docker.sock` +- Windows (Docker Desktop): `//./pipe/docker_engine://./pipe/docker_engine` + +The installer detects the platform and generates the correct bind mount. The `docker_socket` config key allows overriding this in expert mode.