Files
cannamanage/docs/ROO-HANDOVER.md
T
Patrick Plate 6570ea364a
Deploy to Production / test (push) Has been cancelled
Deploy to Production / deploy (push) Has been cancelled
docs: mark CannaManage deploy RESOLVED — live on TrueNAS:3000
Records the three real root causes (BASE_URL metadataBase, Spring Boot 4
Flyway starter, mail health indicator) and the 8080->8081 host port remap.
2026-06-13 10:01:39 +02:00

8.6 KiB

🔁 Roo Handover — CannaManage Docker Deploy on TrueNAS

Date: 2026-06-13
Written by: Lumen (Homelab mode, claude-sonnet-4-6)
For: Next Roo session (new model)


RESOLVED — 2026-06-13 — CannaManage live at http://192.168.188.119:3000

All blocking issues fixed. Stack is up on TrueNAS (backend + db healthy, frontend serving). The frontend pnpm build crash was not a NextAuth problem — the 6 earlier fixes targeted the wrong layer. Three real root causes, fixed in order:

  1. Frontend build crash (ERR_INVALID_URL, input: 'undefined') — commit f6a7143 Root layout src/app/layout.tsx evaluated new URL(process.env.BASE_URL) at module load. BASE_URL was never a build-time ENV → new URL(undefined) threw. Because it's the root layout, its metadata is collected for every route during "Collecting page data", explaining why both /impressum (marketing) and /portal-login (non-marketing) failed identically. Fix: ?? "http://localhost:3000" fallback + BASE_URL build ENV in Dockerfile. The middleware/force-dynamic fixes were irrelevant (metadata is evaluated before middleware ever runs).

  2. Backend crash: Schema validation: missing table [audit_events] — commit 8490da4 This is Spring Boot 4.0.6, which modularized autoconfiguration. FlywayAutoConfiguration moved into a dedicated spring-boot-flyway module pulled in only by spring-boot-starter-flyway. The pom had only flyway-database-postgresql (+ transitive flyway-core) but NOT the starter, so spring.flyway.enabled=true was inert: no migrations ran, no flyway_schema_history, Hibernate ddl-auto=validate failed on the empty schema. Fix: add spring-boot-starter-flyway. Ref: https://spring.io/blog/2025/10/28/modularizing-spring-boot/

  3. Backend unhealthy (503 on /actuator/health) — commit 60844ef spring-boot-starter-mail registers a mail health indicator that tries localhost:1025. No SMTP container in this deployment → DOWN → aggregate health DOWN → Docker marks the container unhealthy → frontend refused to start. Fix: management.health.mail.enabled=false in the docker profile.

Infra note: Host port 8080 was already taken by odysseus-searxng-1. The TrueNAS override (/mnt/VM_SSD_Pool/cannamanage/docker-compose.truenas.yml, not in git) remaps the backend host port to 8081 using ports: !reset [] (compose merges list-type keys by concat otherwise). The internal container port stays 8080, so BACKEND_URL=http://backend:8080 is unaffected.

Verified: frontend /login 200, /impressum 200 (was the failing SSG page), / 307→login; backend /actuator/health UP; reachable from the workstation over LAN.


What We Were Doing

Deploying the full CannaManage stack (Spring Boot backend + Next.js frontend + PostgreSQL) on TrueNAS.local at 192.168.188.119 so Patrick can test the app in a browser.


Current State: ⚠️ Frontend Build Still Failing

Backend: Built and ready (image exists on TrueNAS)
DB: Postgres pulled and ready
Frontend: pnpm build failing inside Docker with ERR_INVALID_URL, input: 'undefined'

Root cause: NextAuth v5 tries to construct its internal URL at static page collection time during next build. It reads AUTH_URL env var and crashes if it's undefined. The marketing pages (/pricing, /impressum, /datenschutz, /agb) are the ones triggering it because the middleware runs on them.


All Fixes Already Applied & Pushed to Gitea

These commits are all on main at http://192.168.188.119:30008/pplate/cannamanage:

Commit Fix
61707ff Added spring-boot-starter-websocket to cannamanage-service/pom.xml
d0c53a9 Fixed DsgvoService.java: getMembershipNumber() + removed setPhone(null)
106229e Added NEXTAUTH_URL as build ARG to frontend Dockerfile
805bc4f Added AUTH_URL + AUTH_SECRET build ARGs (NextAuth v5 uses AUTH_URL)
3e4fdee Added export const dynamic = "force-dynamic" to marketing layout
b57be8a Switched Dockerfile to hardcoded build-time placeholder ENVs
d650987 Guarded auth.ts redirect callback against undefined url
9a4df56 Latest fix — excluded marketing routes from NextAuth middleware matcher

The latest fix (9a4df56) excludes /pricing, /impressum, /datenschutz, /agb from the middleware matcher pattern so NextAuth never runs on those routes during SSG.


How to Resume

Step 1: Pull latest on TrueNAS and rebuild frontend

ssh truenas.local "cd /mnt/VM_SSD_Pool/cannamanage && git pull && docker compose -f docker-compose.yml -f docker-compose.truenas.yml build --no-cache frontend 2>&1 | tail -20"

Step 2: If build succeeds, start the stack

ssh truenas.local "cd /mnt/VM_SSD_Pool/cannamanage && docker compose -f docker-compose.yml -f docker-compose.truenas.yml up -d"

Step 3: Wait for backend to be healthy (Flyway runs migrations on first start)

ssh truenas.local "docker ps --filter name=cannamanage"
# Wait for cannamanage-backend to show (healthy)

Step 4: Load seed data

ssh truenas.local "docker exec -i cannamanage-db psql -U cannamanage -d cannamanage < /mnt/VM_SSD_Pool/cannamanage/scripts/seed/init.sql"

Step 5: Open the app


If Frontend Build Still Fails

The build error is always:

[Error: Failed to collect page data for /pricing]
ERR_INVALID_URL, input: 'undefined'
    at chunk 7624.js (NextAuth internal URL construction)

This is NextAuth v5 initializing its session URL. The last fix excluded the marketing routes from the middleware — if it still fails, the problem is that NextAuth's auth.ts is being imported somewhere in the page tree even without middleware running.

Nuclear option: Add SKIP_ENV_VALIDATION=1 to the frontend builder ENV in the Dockerfile, or better: create a src/auth-server.ts that lazy-initializes auth only at runtime (not build time) and update the pages that import it.

Simpler workaround: Add export const dynamic = "force-dynamic" to each individual marketing page file:

  • src/app/(marketing)/pricing/page.tsx — line 1 after "use client" → add export const dynamic = "force-dynamic"
  • src/app/(marketing)/impressum/page.tsx
  • src/app/(marketing)/datenschutz/page.tsx
  • src/app/(marketing)/agb/page.tsx

Note: "use client" pages can't export dynamic, so it would need to go in the layout instead — which was already tried and didn't work. The real fix is the middleware matcher fix in commit 9a4df56.


Files Modified (all in /home/pplate/IdeaProjects/cannamanage/)

File Change
cannamanage-service/pom.xml +websocket dep
cannamanage-service/src/.../DsgvoService.java method name fix
cannamanage-frontend/Dockerfile build-time ENV placeholders
cannamanage-frontend/src/lib/auth.ts null guard in redirect callback
cannamanage-frontend/src/app/(marketing)/layout.tsx force-dynamic export
cannamanage-frontend/src/middleware.ts marketing routes excluded from matcher

TrueNAS Deploy Location

/mnt/VM_SSD_Pool/cannamanage/
├── docker-compose.yml           (base)
├── docker-compose.truenas.yml   (override: NEXTAUTH_URL=http://192.168.188.119:3000)
├── Dockerfile.backend
├── cannamanage-frontend/
│   └── Dockerfile
└── scripts/seed/init.sql        (seed data)

Seed Data Summary (loaded into DB after first boot)

  • Club: Grüner Daumen e.V., Berlin, max 500 members
  • Admin: admin@test.de / test123 (ROLE_ADMIN)
  • Members: 5 (Max, Anna, Jonas[under-21], Lisa, Tom)
  • Strains: Northern Lights (18.5% THC), Amnesia Haze (22% THC), CBD Critical Mass (5% THC)
  • Batches: 3 available batches (500g, 300g, 200g)
  • Tour guide: docs/TOURGUIDE.md

Container Management Commands

# Status
ssh truenas.local "docker ps --filter name=cannamanage"

# Logs
ssh truenas.local "docker logs cannamanage-backend -f --tail=50"
ssh truenas.local "docker logs cannamanage-frontend -f --tail=50"

# Rebuild specific service
ssh truenas.local "cd /mnt/VM_SSD_Pool/cannamanage && git pull && docker compose -f docker-compose.yml -f docker-compose.truenas.yml up -d --build frontend"

# Stop all
ssh truenas.local "cd /mnt/VM_SSD_Pool/cannamanage && docker compose -f docker-compose.yml -f docker-compose.truenas.yml down"

Generated 2026-06-13 by Lumen (Homelab mode)