--- 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 33–43) - `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.