Files
flixcooks-website/.cursor/plans/coolify_react_cms_stack_ea69bc7d.plan.md
T

325 lines
13 KiB
Markdown
Raw Normal View History

---
name: Coolify React CMS Stack
overview: "Empfohlener Standard-Stack: Next.js (React) + Payload CMS (self-hosted) + PostgreSQL, alles als Docker-Images über GitHub → Coolify. Cursor/MCP für die Entwicklung, GitHub Actions für Qualitätssicherung vor dem Deploy."
todos:
- id: scaffold-monorepo
content: "Greenfield-Monorepo anlegen: apps/web (Next standalone), apps/cms (Payload), packages/shared-types"
status: pending
- id: docker-coolify
content: "Dockerfiles, docker-compose.yml, docs/COOLIFY.md (3 Services: Postgres, CMS, Web) nach FlixCooks-Muster"
status: pending
- id: cms-content-model
content: Payload Collections + Webhooks für On-Demand Revalidation; Env-Beispiele in .env.example
status: pending
- id: github-ci
content: "GitHub Actions: lint, typecheck, build, docker build smoke; branch protection auf main"
status: pending
- id: mcp-agents
content: .cursor/mcp.json + .agents/brain.md mit Stack-, Env- und Deploy-Regeln für KI
status: pending
- id: animation-baseline
content: "GSAP/Lenis/Framer-Baseline-Komponenten und Regel: Overlays stoppen Lenis"
status: pending
isProject: false
---
# Tech-Stack & Workflow: React-Sites, CMS, Docker, Coolify
## Empfehlung (Default)
Du bist unsicher bei CMS und Frontend hier ist ein **bewährtes Default**, das zu deinen Vorgaben passt (React, Animationen, Docker, Coolify, KI/MCP, CI):
| Schicht | Technologie | Warum |
|---------|-------------|--------|
| **Frontend** | [Next.js 15](https://nextjs.org) (App Router, TypeScript) | SEO/SSR/ISR, React-Ökosystem, `output: 'standalone'` für ein schlankes Production-Docker-Image |
| **Animationen** | GSAP (+ ScrollTrigger), Framer Motion, Lenis | GSAP für Scroll/Timeline-Premium-Feel; Framer für UI-Micro-Interactions; Lenis kennst du bereits aus FlixCooks |
| **CMS** | [Payload CMS 3](https://payloadcms.com) (eigener Container) | TypeScript, Postgres-native, Admin-UI out of the box, Docker-freundlich, passt zu Coolify wie dein aktuelles Postgres-Setup |
| **Datenbank** | PostgreSQL 16 (Coolify Database Service) | Eine Instanz, getrennte DBs/User für CMS vs. App optional |
| **Runtime / Deploy** | Docker + [Coolify](https://coolify.io) | Git-Webhook → Build → Traefik/HTTPS; du hast das Muster schon in [docs/COOLIFY.md](docs/COOLIFY.md) |
| **Lokale Dev** | `docker compose` (Web + CMS + Postgres) | Parität zu Production, wie [docker-compose.yml](docker-compose.yml) bei FlixCooks |
| **KI-Entwicklung** | Cursor + MCP-Server | Repo-Kontext, GitHub, Docs, optional DB |
| **CI** | GitHub Actions | Lint, Types, Build, Docker-Smoke, optional E2E; PR-Review wie [.github/workflows/gemini-pr-review.yml](.github/workflows/gemini-pr-review.yml) |
**Alternative Frontend:** Vite + React SPA + nginx-Image maximal frei für reine Animation-Landingpages, aber schlechteres SEO und kein ISR ohne Extra-Aufwand. **Alternative CMS (weniger Ops):** Sanity/Contentful (Cloud) nur Frontend-Container auf Coolify. **Alternative CMS (kein Backend):** Tina/Decap + Markdown im Repo gut für Blogs, schwächer für Redakteur:innen ohne Git.
---
## Zielarchitektur auf Coolify
```mermaid
flowchart TB
subgraph dev [Entwicklung]
Cursor[Cursor + MCP]
LocalCompose[docker compose]
Cursor --> LocalCompose
end
subgraph github [GitHub]
Repo[Monorepo]
GHA[GitHub Actions CI]
Repo --> GHA
end
subgraph coolify [Coolify Server]
PG[(PostgreSQL)]
CMS[Payload CMS Container]
WEB[Next.js Container]
Traefik[Traefik HTTPS]
PG --> CMS
CMS -->|REST/GraphQL| WEB
Traefik --> WEB
Traefik --> CMS
end
dev -->|push main| Repo
GHA -->|grüner Build| Repo
Repo -->|Webhook Deploy| coolify
```
**Drei Coolify-Ressourcen** (analog zu deinem FlixCooks-Setup: Postgres + App):
1. **PostgreSQL** internal URL, nicht öffentlich
2. **CMS-App** Dockerfile aus `apps/cms`, Port z. B. 3001, Env: `DATABASE_URL`, `PAYLOAD_SECRET`
3. **Web-App** Dockerfile aus `apps/web`, Port 3000, Env: `CMS_URL` (internal), `REVALIDATE_SECRET` für On-Demand-ISR
Persistenz: Postgres-Volume (Inhalte), optional Volume für CMS-Uploads (`/app/media`).
---
## Repository-Struktur (Greenfield-Vorlage)
Ein Repo pro „Site-Familie“ oder Monorepo für mehrere Marken:
```
my-site/
├── apps/
│ ├── web/ # Next.js
│ │ ├── Dockerfile
│ │ ├── src/
│ │ └── next.config.ts # output: 'standalone'
│ └── cms/ # Payload
│ ├── Dockerfile
│ └── payload.config.ts
├── packages/
│ └── shared-types/ # optional: gemeinsame TS-Typen CMS ↔ Web
├── docker-compose.yml # lokaler Prod-Parität-Stack
├── docker-compose.dev.yml # nur Postgres (wie bei FlixCooks)
├── .github/workflows/
│ ├── ci.yml
│ └── gemini-pr-review.yml # optional, aus FlixCooks übernehmen
├── .cursor/
│ └── mcp.json # MCP-Server für das Team
├── .agents/
│ ├── brain.md # Architektur für KI (Pattern aus FlixCooks)
│ └── rules/AGENT.md
└── docs/
└── COOLIFY.md
```
---
## Frontend-Stack (React + Animationen)
**Kern:**
- **Next.js App Router** Seiten in `app/`, Server Components für CMS-Daten, Client Components nur für Animation/Interaktion
- **TypeScript** strikt; Typen aus Payload generieren (`payload generate:types`)
- **Styling** CSS Modules oder Tailwind (nur wenn du es willst; FlixCooks bleibt bei Vanilla CSS für neue React-Sites ist Tailwind optional, nicht Pflicht)
**Animation-Toolkit:**
| Tool | Einsatz |
|------|---------|
| **GSAP + ScrollTrigger** | Hero-Sequences, pinned Sections, komplexe Timelines |
| **Framer Motion** | Hover, Page-Transitions, modale UI |
| **Lenis** | Smooth Scroll (wie FlixCooks: bei Overlays `lenis.stop()`) |
| **(optional) @react-three/fiber** | 3D-Hero nur wenn nötig |
**CMS-Anbindung im Web:**
- **Build-Zeit (SSG):** `generateStaticParams` + Fetch von Payload REST für Marketing-Seiten
- **On-Demand Revalidation:** Payload-Webhook → `POST /api/revalidate?secret=...` in Next.js (Inhalt ändert sich ohne Full-Redeploy)
- **Preview:** Draft-Modus mit Payload Preview-URL + Next `draftMode()`
Env im Web-Container (Coolify):
- `CMS_URL=http://payload-service:3001` (internal hostname)
- `REVALIDATE_SECRET`, `NEXT_PUBLIC_SITE_URL`
---
## CMS-Stack (Payload auf Coolify)
**Warum Payload als Default:** Self-hosted, eine Postgres-URL, Admin unter `/admin`, Collections/Blocks für Seitenmodule, Media-Uploads, Webhooks alles containerisierbar.
**Coolify Env (CMS):**
- `DATABASE_URL` internal Postgres URL (gleiches Muster wie [docs/COOLIFY.md](docs/COOLIFY.md) Zeilen 3343)
- `PAYLOAD_SECRET` langer Zufallswert (nur Secrets, nie ins Repo)
- `NEXT_PUBLIC_SERVER_URL` öffentliche CMS-URL (für Admin-Assets)
**Erstes Deployment:** analog FlixCooks `RUN_DB_SEED` einmalig Migration/Seed, danach Flag entfernen.
**Sicherheit:** CMS-Admin nur über HTTPS; CORS auf Web-Domain beschränken; API-Keys für Preview/Revalidate nur als Secrets.
---
## Docker-Images
### Web (`apps/web/Dockerfile`) Next standalone
Mehrstufig: `node:22-alpine``npm ci``npm run build` → Runtime nur `.next/standalone` + `static` + `public`.
- `EXPOSE 3000`
- `HEALTHCHECK` auf `/api/health` (kleine Route: `{ "status": "ok" }`)
- Coolify: Port **3000**, Health Path `/api/health`
### CMS (`apps/cms/Dockerfile`)
Payload-Official-Pattern oder Node-Image mit `npm run build && npm run start`.
- `HEALTHCHECK` auf CMS-Health-Endpoint
- Volume für `/app/media` (Uploads überleben Redeploy)
### Lokales Parität-Compose
Orientierung an deinem bestehenden [docker-compose.yml](docker-compose.yml):
- `postgres` mit `healthcheck`
- `cms` `depends_on: postgres: service_healthy`
- `web` `depends_on: cms` + `DATABASE_URL` nur wenn Web eigene DB braucht (meist nicht nur CMS nutzt DB)
Entrypoint-Pattern von [docker/entrypoint.sh](docker/entrypoint.sh) übernehmen: **DB warten → Migration → dann Prozess starten**.
---
## Coolify-Workflow (End-to-End)
```mermaid
sequenceDiagram
participant Dev as Developer
participant GH as GitHub
participant GHA as GitHub Actions
participant CF as Coolify
participant Web as Next Container
participant CMS as Payload Container
Dev->>GH: push feature branch
Dev->>GH: open PR
GHA->>GHA: lint typecheck build docker
GHA-->>Dev: PR checks green
Dev->>GH: merge to main
GH->>CF: webhook deploy
CF->>CF: build CMS image
CF->>CF: build Web image
CF->>Web: rolling update
CMS->>Web: optional revalidate webhook
```
**Coolify-Konfiguration pro App:**
| Setting | Web | CMS |
|---------|-----|-----|
| Build Pack | Dockerfile | Dockerfile |
| Branch | `main` | `main` |
| Port | 3000 | 3001 |
| Health | `/api/health` | `/api/health` oder Payload-Default |
| Secrets | `REVALIDATE_SECRET`, `CMS_URL` | `DATABASE_URL`, `PAYLOAD_SECRET` |
**Checkliste Erstdeploy** (aus [docs/COOLIFY.md](docs/COOLIFY.md) übertragbar):
1. Postgres healthy, internal URL notieren
2. CMS deployen, Admin anlegen, Collections seeden
3. Web deployen mit internal `CMS_URL`
4. Domain + HTTPS (Traefik)
5. Webhook Payload → Next Revalidate testen
6. `RUN_DB_SEED` / Migration-Flags wieder aus
---
## GitHub Actions (CI vor Coolify)
**Workflow `ci.yml`** (bei jedem PR + push auf `main`):
1. **checkout**
2. **Node 22** + Cache (`apps/web`, `apps/cms`)
3. **Parallel jobs oder Matrix:**
- `npm run lint` (ESLint)
- `npm run typecheck` (`tsc --noEmit`)
- `npm run build` (Web + CMS)
4. **Docker build test** (ohne Push):
- `docker build -f apps/web/Dockerfile apps/web`
- `docker build -f apps/cms/Dockerfile apps/cms`
5. **(optional) Playwright** gegen `docker compose up` Smoke: Startseite, eine CMS-Seite, Health endpoints
6. **(optional) PR Review** bestehendes Gemini-Workflow aus FlixCooks wiederverwenden
**Branch-Schutz:** `main` nur mit grünen Required Checks mergebar.
Coolify deployt **nach** Merge CI blockiert kaputte Images, Coolify baut das echte Production-Image (oder du pushst zu GHCR für den Start reicht Coolify-eigener Build).
---
## KI-gestützte Entwicklung mit MCP
**Cursor `mcp.json` (Team-Standard):**
| MCP | Zweck |
|-----|--------|
| **GitHub** | Issues, PRs, Actions-Logs aus dem Chat |
| **Context7** (oder Fetch) | Aktuelle Next.js / Payload / GSAP-Docs |
| **Postgres** (optional, nur Dev) | Content/Debugging nie Production-Credentials im Repo |
| **Filesystem** | Standard in Cursor |
**Projekt-Wissen für Agenten** (aus FlixCooks übernehmen):
- [.agents/brain.md](.agents/brain.md) Architektur, Env-Regeln, Coolify-Hosts
- [.agents/rules/AGENT.md](.agents/rules/AGENT.md) Commit/PR/TODO-Konventionen
- `docs/COOLIFY.md` Deploy-Runbook pro Projekt
**Typischer KI-Workflow:**
1. Ticket/Issue in GitHub (MCP)
2. Feature-Branch; Agent ändert `apps/web` + Payload-Collection
3. `docker compose up` lokal; Agent nutzt Health-URLs
4. PR → CI grün → Gemini-Review optional
5. Merge → Coolify
---
## Entwickler-Alltag (Kurzablauf)
1. `cp .env.example .env` lokale URLs
2. `docker compose -f docker-compose.dev.yml up -d` (nur Postgres) **oder** volles `docker compose up`
3. `npm run dev` in `apps/web` und `apps/cms` (schneller Hot Reload) **oder** alles in Containern
4. In Payload Inhalte pflegen → Webhook triggert Revalidate
5. `git push` → PR → CI → merge → Coolify rebuild
---
## Bezug zu FlixCooks (dieses Repo)
FlixCooks ist heute **Vanilla PHP + Postgres + eingebautes `admin.php`-CMS** kein React. Das ist ein **paralleler Stack**, kein Widerspruch:
| Aspekt | FlixCooks (aktuell) | Neuer React-Stack |
|--------|---------------------|-------------------|
| Frontend | PHP-Templates | Next.js + React |
| CMS | `admin.php` | Payload (Container) |
| DB | Postgres | Postgres |
| Deploy | [Dockerfile](Dockerfile) + [COOLIFY.md](docs/COOLIFY.md) | gleiches Muster, zwei App-Services |
| Animationen | Lenis, Vanilla CSS | Lenis + GSAP + Framer |
Du kannst FlixCooks auf Coolify weiterbetreiben und **neue Projekte** im Monorepo-Template starten. Eine spätere Migration FlixCooks → Next wäre ein separates Projekt (Content-Export aus Postgres/JSON → Payload-Collections).
---
## Nächste konkrete Schritte (nach Plan-Freigabe)
1. **Greenfield-Repo** aus der Struktur oben scaffolden (oder `create-payload-app` + Next in Monorepo).
2. **Minimale Collections** in Payload: `pages`, `recipes` (oder `projects`), `siteSettings`, Media.
3. **Dockerfiles + compose** + `docs/COOLIFY.md` vom FlixCooks-Muster kopieren/adaptieren.
4. **GitHub Actions `ci.yml`** anlegen.
5. **Coolify:** Postgres → CMS → Web → Webhook Revalidate testen.
6. **`.cursor/mcp.json` + `.agents/brain.md`** für das neue Repo.
Wenn du willst, kann im nächsten Schritt ein **konkretes Starter-Repo** (Dateien + minimale Hero-Animation + eine Payload-Collection) direkt in einem neuen Ordner oder Branch angelegt werden.