# Homelab release tooling — onboard + publish new alpha apps cheaply (2026-06-22) **From:** Homelab Lumen → **For:** Work Lumen **Why:** So you can take the next alpha project (starting in a few weeks) from zero → TrueNAS-hosted → public HTTPS in minutes, without re-discovering the whole DevOps chain. The pattern is proven twice (InspectFlow, CannaManage). Everything below is in Gitea now. ## TL;DR — three artifacts, all pushed 1. **Runbook + port registry** — [`plans/homelab-release-runbook.md`](../../plans/homelab-release-runbook.md:1) The authoritative procedure. Start here. Contains the **single-source-of-truth port/subdomain registry** — allocate ports here *before* writing any config. Next free frp remotePort = **30011**. 2. **Template repo** — `pplate/homelab-app-template` on Gitea (`http://192.168.188.119:30008/pplate/homelab-app-template`). Marked as a Gitea template. Ships the working `deploy.yml`, both compose files, `.env.example`, and ⭐ the auth-token proxy (`frontend/.../api/backend/[...path]/route.ts`) — the systemic fix for the ~9-day CannaManage auth blocker. Generate a new repo from it, run one sed to substitute placeholders, set 3 secrets, push. 3. **Publish switch** — [`scripts/homelab-publish.sh`](../../scripts/homelab-publish.sh:1) One idempotent command to flip a locally-hosted app to public HTTPS (frpc block + IONOS vhost + Let's Encrypt cert + reloads + verify). `--dry` to preview, `--down` to unpublish. App keeps running locally either way. ## The design Patrick asked for: local-first, public via a switch - **Phase 1 (local):** `git push` → instance-level act_runner on TrueNAS builds + runs the stack → live at `http://192.168.188.119:`. **Zero VPS / IONOS touch.** Every project starts and stays here during early alpha. - **Phase 2 (public):** purely additive. `./scripts/homelab-publish.sh `. Nothing about the app changes; you only add a tunnel out. Reversible with `--down`. ## Fastest path for the next project ```bash # 1. Allocate in the runbook §2 registry: frpPort=30011, frontendPort=3001, # backendPort=8082, subdomain=.plate-software.de. Commit that edit. # 2. New repo from template (Gitea UI "Use this template", or copy the dirs). # 3. Substitute placeholders (recipe in the template README), remove the # template-guard `if:` line in deploy.yml. # 4. Set Gitea Actions secrets: AUTH_SECRET, JWT_SECRET, DB_PASSWORD. # 5. git push → live on LAN. Test there as long as you want. # 6. When ready for web testers: create DNS A-record → 82.165.206.45, then # ./scripts/homelab-publish.sh 3001 30011 .plate-software.de ``` ## Gotchas already baked in (don't relearn these the hard way) - **Auth:** use NextAuth v5 `auth()`, never `getToken()` (its `__Secure-` cookie detection breaks across the HTTPS→HTTP proxy boundary). The proxy route injects the Bearer token server-side. **Never delete that route file.** - **db internal-only:** `ports: !override []` — no LAN Postgres. Verified live on CannaManage (no host :5432 listener). - **Postgres password rotation:** `POSTGRES_PASSWORD` only applies on first volume init; deploy.yml has an `ALTER USER` reconcile step for existing volumes. - **Frontend verify:** container-loopback node probe, not host wget (host probe gave transient false-failures mid-recreate — cost a confusing debug session). - **acme.sh:** pin Let's Encrypt (`--set-default-ca --server letsencrypt`). The default ZeroSSL stalled (order stuck at retryafter=86400). - **DNS A-records point at IONOS (82.165.206.45)**, NOT the VPS. The VPS (85.214.154.199) only runs frps; Apache on IONOS terminates TLS and proxies in. - **Stale workstation DNS:** verify public with `curl --resolve :443:82.165.206.45 https:///`. ## State of the reference deploys - **CannaManage** is LIVE at https://cannamanage.plate-software.de (frp 30010, frontend 3000, backend 8081). See [`2026-06-22-cannamanage-public-hosting-LIVE.md`](2026-06-22-cannamanage-public-hosting-LIVE.md:1) for its full verification + the 6 open follow-ups (PII/GDPR backups, secret rotation, accessToken client-exposure, ci.yml red, etc.). - **InspectFlow** = the Caddy-fronted variant (frp 30009). The template follows the simpler CannaManage shape (frontend-only tunnel, no Caddy). ## Note for me-next-time The old [`plans/homelab-proxy-architecture.md`](../../plans/homelab-proxy-architecture.md:1) describes a WireGuard plan that was **never used** (VPS is OpenVZ — no WireGuard). The runbook is the current truth; treat that old doc as historical.