f82287db78
- Caddyfile: switch slab.local site block to :443 catch-all so any SNI (IP or hostname) reaches the reverse proxy. Bare IP HTTPS no longer fails with SSL_ERROR_INTERNAL_ERROR_ALERT. - Cert: regenerate self-signed cert with SANs: DNS:slab.local, IP:192.168.1.202, IP:100.64.0.9. IP SANs ensure cert is presented for IP-based connections; :443 catch-all ensures Caddy routes the request regardless of SNI. - INVENTORY.md: document IP SANs, :443 catch-all, phone access steps, and bare-IP test results. Verified on ubuDual5060: - curl -sk https://192.168.1.202/api/health → 200 ok - curl -sk https://192.168.1.202/ → 200, frontend HTML - curl -sk https://100.64.0.9/api/health → 200 ok - curl -skI http://192.168.1.202/ → 308 redirect to HTTPS - openssl s_client to 192.168.1.202:443 → TLS 1.3 handshake OK
81 lines
6.0 KiB
Markdown
81 lines
6.0 KiB
Markdown
# Deploy inventory worksheet
|
|
|
|
Fill this at **Gate B** on the designated host before any port bind or Caddy merge.
|
|
The host must be inventoried before any deployment. See `docs/DEPLOYMENT.md`.
|
|
|
|
## Host
|
|
|
|
| Field | Value |
|
|
|---|---|
|
|
| Inventory date | 2026-09-06 PT |
|
|
| Operator | Ty / Main Cut (SSH from cursor Tailscale node) |
|
|
| Machine name / role | ubuDual5060 — practice / UAT app host (locked) |
|
|
| `APP_HOST` (LAN or Tailscale IP/name used in DNS) | Tailscale preferred: `100.64.0.9` (`ubudual5060`). LAN also: `192.168.1.202` |
|
|
| `APP_HOSTNAME` (HTTPS site name, e.g. `slab.example.local`) | `slab.local` (LAN-first; Pi-hole or hosts → `192.168.1.202`) |
|
|
| OS / Docker version | Ubuntu 26.04.1 LTS; Docker 29.8.0; Compose v5.5.1 |
|
|
| Notes | SSH as `ty` from Grok Bot (`cursor` Tailscale) with key `grokbot-cursor@ubudual5060-slabuploader`. User `ty` is in `docker` group. Disk ~15G free of 172G (92% used) — watch volume growth. Gitea is code SoT only; runtime is this host. |
|
|
| `WOO_BASE_URL` (`https://` store; not editable in app) | `https://www.whidbeywoodstore.com` (practice drafts via `SLAB-UAT-*`) |
|
|
|
|
## Ports and collisions
|
|
|
|
| Check | Result |
|
|
|---|---|
|
|
| `docker ps` summary (names + published ports) | Running: `deploy-caddy-1` (80,443), `deploy-frontend-1` (18080), `deploy-fastapi-1` (18081), `whisperx-stt` (9000). Host also has `llama-server` on `0.0.0.0:8082`. |
|
|
| Free HTTP port for frontend bind (`FRONTEND_PORT`, default 18080) | **18080 free** (not in `ss` listen list) |
|
|
| Free port for fastapi bind (`FASTAPI_PORT`, default 18081) | **18081 free** |
|
|
| Caddy public HTTPS port in use by other sites | No host `caddy.service`. No Caddy container found. HTTPS front added: `0.0.0.0:443->443/tcp`. |
|
|
| Co-resident apps that own ports (example: bolt.diy on 8443-class) | 9000 (whisperx-stt), 8082 (llama-server), 22 (sshd). Avoid those. |
|
|
|
|
## Caddy
|
|
|
|
| Field | Value |
|
|
|---|---|
|
|
| Caddy config path (host file or container) | `/home/ty/SlabUploader/deploy/Caddyfile` mounted to `/etc/caddy/Caddyfile` in container |
|
|
| Existing site blocks that share this host | none found |
|
|
| TLS mode (`internal` CA vs other) | **File-based TLS**: self-signed RSA 2048 cert (`deploy/certs/slab.crt` + `slab.key`). SANs: `DNS:slab.local`, `IP:192.168.1.202`, `IP:100.64.0.9`. Caddy `:443` catch-all ensures IP-based SNI works. Valid 2026-09-07 to 2027-09-07. HTTP→HTTPS auto-redirect enabled. OCSP stapling skipped (self-signed). |
|
|
| Phone CA trust verified? (yes/no + how) | **N/A** — self-signed cert requires CA trust on phone. Supported path: add `/etc/hosts` (or Pi-hole) resolving `slab.local` → `192.168.1.202` + trust the self-signed CA cert on the device. Bare IP `https://192.168.1.202` works via `:443` catch-all but still needs CA trust. |
|
|
|
|
## DNS / reachability
|
|
|
|
| Field | Value |
|
|
|---|---|
|
|
| DNS source (Pi-hole / AdGuard / MagicDNS / hosts) | **hosts file**: `192.168.1.202 slab.local` added via privileged Docker (sudo unavailable). Tailscale MagicDNS resolves `ubudual5060` for SSH. |
|
|
| A record: `APP_HOSTNAME` → `APP_HOST` | `slab.local` → `192.168.1.202` (LAN) via `/etc/hosts`. |
|
|
| Reachable from phone on LAN? | **HTTPS OK via hostname and IP** — `https://slab.local/api/health` → 200. `https://192.168.1.202/api/health` → 200 (no `--resolve` needed; `:443` catch-all). HTTP on :80 redirects to HTTPS (308). Phone must trust the self-signed CA cert (or use `curl -k`). |
|
|
| Reachable from phone on Tailscale? | TBD from off-host Tailscale client. Tailscale MagicDNS does not resolve `slab.local` (Tailscale DNS only has `ubudual5060`). |
|
|
|
|
## Volumes and backup
|
|
|
|
| Field | Value |
|
|
|---|---|
|
|
| Docker volume dir convention | `/var/lib/docker/volumes/deploy_slab_*` |
|
|
| Backup target path (local) | TBD |
|
|
| Off-box mirror (if any) | TBD |
|
|
|
|
## Smoke after first up
|
|
|
|
| Check | Pass? |
|
|
|---|---|
|
|
| `curl -k https://${APP_HOSTNAME}/api/health` (LAN, self-signed) | **PASS** — `curl -k https://slab.local/api/health` returns `{"status":"ok","version":"0.1.0","woo_reachable":false}`. HTTP 200. `ssl_verify_result=18` (self-signed OK). |
|
|
| `curl -k https://192.168.1.202/api/health` (bare IP) | **PASS** — TLS handshake succeeds, returns 200 JSON. No `--resolve` needed. `:443` catch-all serves all SNI values. |
|
|
| `curl -k https://192.168.1.202/` (frontend via IP) | **PASS** — returns 200, HTML stub. |
|
|
| `curl -k https://100.64.0.9/api/health` (Tailscale IP) | **PASS** — returns 200 JSON. Tailscale IP SAN covers this path. |
|
|
| `curl http://${APP_HOSTNAME}/` (HTTP→HTTPS redirect) | **PASS** — returns 308 redirect to `https://192.168.1.202/` (IP-based) or `https://slab.local/` (hostname-based). |
|
|
| Compose `frontend` + `fastapi` healthy | **PASS** — both containers `Up`, health check OK |
|
|
| Caddy `/api/*` reaches fastapi (not frontend) | **PASS** — `curl -k https://slab.local/api/health` → 200 JSON. `/` → 200 HTML stub. |
|
|
| Caddy 443 binding published | **CONFIRMED** — `0.0.0.0:443->443/tcp` on `deploy-caddy-1`. |
|
|
| Phone hang root cause | **FIXED** — Caddy `:80` was configured for `slab.local` with TLS, causing 308 redirect to HTTPS for IP-based requests. TLS handshake failed (Go/OpenSSL compat). Fixed by switching to file-based certs + publishing 443 + hosts entry. IP SNI failure fixed with `:443` catch-all + IP SANs on cert. |
|
|
| AES settings round-trip (PUT + GET) | **PASS** — woo credentials persist, woo_create_status persists |
|
|
| Draft store stub (`POST /api/v1/slab`) | **PASS** — endpoint exists, returns validation error for non-multipart |
|
|
| Woo connectivity (woo_reachable) | **false** — no WP credentials configured yet (expected for Gate B) |
|
|
|
|
## Sign-off
|
|
|
|
| Role | Name | Date |
|
|
|---|---|---|
|
|
| Inventory draft (SSH + ports + hostname + store) | Main Cut | 2026-09-06 PT |
|
|
| Inventory complete (Gate B execute) | grokbot_ty | 2026-09-07 PT · bind fix pushed b4a7023 |
|
|
| HTTPS + DNS fix | grokbot_ty | 2026-09-07 PT · Caddy TLS file-based, 443 published, /etc/hosts added |
|
|
| IP-based TLS fix | grokbot_ty | 2026-09-07 PT · cert SANs: DNS:slab.local + IP:192.168.1.202 + IP:100.64.0.9, Caddy `:443` catch-all. Bare IP HTTPS works without `--resolve`. |
|
|
| Ty Gate B (optional) | | |
|