Update .env.example for local and production database configurations, ensuring clarity on usage. Modify .gitattributes to enforce LF line endings for shell scripts. Enhance README.md with Docker and Coolify setup instructions for production deployment.
This commit is contained in:
@@ -0,0 +1,324 @@
|
||||
---
|
||||
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.
|
||||
Reference in New Issue
Block a user