# Payload CMS Multi-Tenant Project ## Projektübersicht Multi-Tenant CMS für 4 Websites unter einer Payload CMS 3.x Instanz: - porwoll.de - complexcaresolutions.de - gunshin.de - zweitmein.ng ## Tech Stack - **CMS:** Payload CMS 3.x - **Framework:** Next.js 15.4.7 - **Sprache:** TypeScript - **Datenbank:** PostgreSQL 17 (separater Server) - **Reverse Proxy:** Caddy 2.10.2 mit Let's Encrypt - **Process Manager:** PM2 - **Package Manager:** pnpm ## Architektur ``` Internet → 37.24.237.181 → Caddy (443) → Payload (3000) ↓ PostgreSQL (10.10.181.101:5432) ``` | Server | IP | Funktion | | --------------------- | ------------- | ---------- | | sv-payload (LXC 700) | 10.10.181.100 | App Server | | sv-postgres (LXC 701) | 10.10.181.101 | Datenbank | ## Wichtige Pfade ``` /home/payload/payload-cms/ # Projektroot ├── src/ │ ├── payload.config.ts # Haupt-Konfiguration │ └── collections/ │ ├── Users.ts │ ├── Media.ts │ └── Tenants.ts ├── .env # Umgebungsvariablen ├── ecosystem.config.cjs # PM2 Config └── .next/ # Build Output ``` ## Umgebungsvariablen (.env) ```env DATABASE_URI=postgresql://payload:Finden55@10.10.181.101:5432/payload_db PAYLOAD_SECRET=a53b254070d3fffd2b5cfcc3 PAYLOAD_PUBLIC_SERVER_URL=https://pl.c2sgmbh.de NEXT_PUBLIC_SERVER_URL=https://pl.c2sgmbh.de NODE_ENV=production PORT=3000 ``` ## Multi-Tenant Plugin Verwendet `@payloadcms/plugin-multi-tenant` für Mandantenfähigkeit. **Aktuelle Tenants:** | ID | Name | Slug | |----|------|------| | 1 | porwoll.de | porwoll | | 4 | Complex Care Solutions GmbH | c2s | | 5 | Gunshin | gunshin | **User-Tenant-Zuweisung:** Tabelle `users_tenants` ## Wichtige Befehle ```bash # Entwicklung pnpm dev # Production Build pnpm build # Migrationen pnpm payload migrate:create pnpm payload migrate # ImportMap nach Plugin-Änderungen pnpm payload generate:importmap # PM2 pm2 status pm2 logs payload pm2 restart payload # Datenbank prüfen PGPASSWORD=Finden55 psql -h 10.10.181.101 -U payload -d payload_db ``` ## Workflow nach Code-Änderungen 1. Code ändern 2. `pnpm build` 3. `pm2 restart payload` 4. Testen unter https://pl.c2sgmbh.de/admin ## Bekannte Besonderheiten - **ES Modules:** package.json hat `"type": "module"`, daher PM2 Config als `.cjs` - **Plugin ImportMap:** Nach Plugin-Änderungen `pnpm payload generate:importmap` ausführen - **User-Tenant-Zuweisung:** Neue User müssen manuell Tenants zugewiesen bekommen ## Build-Konfiguration Der Build ist für speichereffizientes Kompilieren optimiert: - `package.json`: `--max-old-space-size=2048` (2GB Heap-Limit) - `next.config.mjs`: `experimental.cpus: 1`, `workerThreads: false` **WICHTIG:** Der Server hat nur 4GB RAM ohne Swap. Bei laufendem VS Code Server muss der Build mit reduziertem Memory ausgeführt werden: ```bash pm2 stop payload # Speicher freigeben NODE_OPTIONS="--no-deprecation --max-old-space-size=1024" ./node_modules/.bin/next build pm2 start payload ``` Ohne PM2-Stop und mit VS Code wird der Build vom OOM Killer beendet (Exit code 137). ## Mehrsprachigkeit (i18n) Das System unterstützt Deutsch (default) und Englisch: - **Admin UI:** `@payloadcms/translations` für DE/EN - **Content:** Localization mit Fallback auf Deutsch - **Datenbank:** 36 `_locales` Tabellen für lokalisierte Felder - **API:** `?locale=de` oder `?locale=en` Parameter - **Frontend:** Routing über `/[locale]/...` ```bash # Locales in der Datenbank prüfen PGPASSWORD=Finden55 psql -h 10.10.181.101 -U payload -d payload_db -c "\dt *_locales" ``` ## URLs - **Admin Panel:** https://pl.c2sgmbh.de/admin - **API:** https://pl.c2sgmbh.de/api ## Datenbank-Direktzugriff ````bash PGPASSWORD=Finden55 psql -h 10.10.181.101 -U payload -d payload_db # Nützliche Queries SELECT * FROM tenants; SELECT * FROM users_tenants; \dt -- Alle Tabellen ```All ````