6570ea364a
Records the three real root causes (BASE_URL metadataBase, Spring Boot 4 Flyway starter, mail health indicator) and the 8080->8081 host port remap.
196 lines
8.6 KiB
Markdown
196 lines
8.6 KiB
Markdown
# 🔁 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
|
|
```bash
|
|
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
|
|
```bash
|
|
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)
|
|
```bash
|
|
ssh truenas.local "docker ps --filter name=cannamanage"
|
|
# Wait for cannamanage-backend to show (healthy)
|
|
```
|
|
|
|
### Step 4: Load seed data
|
|
```bash
|
|
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
|
|
- Frontend: **http://192.168.188.119:3000**
|
|
- Login: `admin@test.de` / `test123`
|
|
- Backend health: http://192.168.188.119:8080/actuator/health
|
|
|
|
---
|
|
|
|
## 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
|
|
|
|
```bash
|
|
# 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)*
|