Files
homelab-app-template/README.md
T

3.4 KiB

homelab-app-template

Scaffold for a new homelab alpha app that deploys to TrueNAS via Gitea Actions and can be publicly hosted over HTTPS with one script. Encodes the proven InspectFlow / CannaManage pattern so Work Lumen can onboard a project in minutes, not days.

Read first: homelab-release-runbook.md — the authoritative procedure and the port/subdomain registry (allocate your ports there before touching configs).


What's in the box

.gitea/workflows/deploy.yml          push-to-main → build + run on TrueNAS
docker-compose.yml                   base: db + backend + frontend
docker-compose.truenas.yml           homelab override: ports, secrets, db internal-only
frontend/src/app/api/backend/[...path]/route.ts   ⭐ the auth-token proxy fix
.env.example                         secret names + how to generate them

You bring the actual app code (Spring backend in backend/, Next.js frontend in frontend/). The template wires the deploy + auth + hosting plumbing only.


Onboard a new project (local phase)

  1. Allocate a frp remotePort + frontend/backend host ports + subdomain in the registry (runbook §2). Next free frp port lives there.

  2. Substitute placeholders. From the new repo root:

    PROJECT=myapp
    FRONTEND_PORT=3001        # unique LAN host port
    BACKEND_PORT=8082         # unique LAN host port (or remove backend ports block)
    SUBDOMAIN=myapp.plate-software.de
    
    grep -rlZ '__PROJECT__\|__FRONTEND_PORT__\|__BACKEND_PORT__\|__SUBDOMAIN__' . \
      | xargs -0 sed -i \
        -e "s/__PROJECT__/$PROJECT/g" \
        -e "s/__FRONTEND_PORT__/$FRONTEND_PORT/g" \
        -e "s/__BACKEND_PORT__/$BACKEND_PORT/g" \
        -e "s/__SUBDOMAIN__/$SUBDOMAIN/g"
    
  3. Set Gitea Actions secrets (repo → Settings → Actions → Secrets): AUTH_SECRET, JWT_SECRET, DB_PASSWORD. Generate:

    for s in AUTH_SECRET JWT_SECRET DB_PASSWORD; do echo "$s=$(openssl rand -base64 32)"; done
    
  4. Remove the template guard in .gitea/workflows/deploy.yml — delete the line if: ${{ gitea.repository != 'pplate/homelab-app-template' }} (it exists only so the bare template repo doesn't try to deploy unsubstituted placeholders).

  5. Push to main. The instance-level act_runner on TrueNAS auto-deploys. App is live at http://192.168.188.119:$FRONTEND_PORT. Done — you can stay here for the whole early-alpha period.

Go public (additive switch, when ready)

# DNS A-record $SUBDOMAIN → 82.165.206.45 must exist first.
./scripts/homelab-publish.sh $PROJECT $FRONTEND_PORT $FRP_REMOTE_PORT $SUBDOMAIN

(homelab-publish.sh lives in the pi_mcps repo scripts/.) Verify per runbook §5.


Why this template exists

  • The auth fix. frontend/.../api/backend/[...path]/route.ts injects the Bearer token server-side via auth(). A static Next rewrite cannot do this and silently breaks auth — the ~9-day CannaManage blocker. Never delete this file.
  • db is internal-only (ports: !override []) — no LAN Postgres exposure.
  • Password rotation reconcile in deploy.yml handles the persistent-volume POSTGRES_PASSWORD gotcha.
  • Frontend verify uses a container-loopback node probe (no transient false-failures from host-port timing).

See the runbook for the full topology, auth gotchas (NextAuth v5 auth() vs getToken()), and the Let's Encrypt CA pin.