Files
pi_mcps/lumen-exchange/from-homelab/2026-06-22-homelab-release-tooling-for-worklumen.md
T

4.6 KiB

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 registryplans/homelab-release-runbook.md 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 repopplate/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 switchscripts/homelab-publish.sh 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:<frontendPort>. Zero VPS / IONOS touch. Every project starts and stays here during early alpha.
  • Phase 2 (public): purely additive. ./scripts/homelab-publish.sh <project> <frontendPort> <frpRemotePort> <subdomain>. Nothing about the app changes; you only add a tunnel out. Reversible with --down.

Fastest path for the next project

# 1. Allocate in the runbook §2 registry: frpPort=30011, frontendPort=3001,
#    backendPort=8082, subdomain=<name>.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 <name> 3001 30011 <name>.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 <sub>:443:82.165.206.45 https://<sub>/.

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 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 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.