mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 18:34:13 +00:00
Tests: - Update frontend.e2e.spec.ts with locale testing - Add search.e2e.spec.ts for search functionality - Add i18n.int.spec.ts for localization tests - Add search.int.spec.ts for search integration - Update playwright.config.ts Documentation: - Add CLAUDE.md with project instructions - Add docs/ directory with detailed documentation - Add scripts/ for utility scripts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
277 lines
8.1 KiB
Markdown
277 lines
8.1 KiB
Markdown
# Payload CMS Multi-Tenant Infrastructure
|
|
|
|
## Übersicht
|
|
|
|
Diese Dokumentation beschreibt die Infrastruktur eines Payload CMS 3.x Multi-Tenant-Systems für den Betrieb mehrerer Websites unter einer zentralen CMS-Instanz.
|
|
|
|
## Architektur
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ INTERNET │
|
|
│ │ │
|
|
│ 37.24.237.181 (Public IP) │
|
|
│ │ │
|
|
│ NAT (Proxmox) │
|
|
│ Port 80, 443 │
|
|
└────────────────────────────┼────────────────────────────────────┘
|
|
│
|
|
┌────────────────────────────┼────────────────────────────────────┐
|
|
│ VLAN 181 │
|
|
│ 10.10.181.0/24 │
|
|
│ │ │
|
|
│ ┌───────────────────────┴───────────────────────┐ │
|
|
│ │ │ │
|
|
│ ▼ ▼ │
|
|
│ ┌─────────────────────┐ ┌─────────────────────┐ │
|
|
│ │ LXC 700 │ │ LXC 701 │ │
|
|
│ │ sv-payload │ │ sv-postgres │ │
|
|
│ │ 10.10.181.100 │────────────────▶│ 10.10.181.101 │ │
|
|
│ │ │ Port 5432 │ │ │
|
|
│ │ - Caddy (80/443) │ │ - PostgreSQL 17 │ │
|
|
│ │ - Node.js 22 │ │ │ │
|
|
│ │ - Payload CMS │ │ │ │
|
|
│ │ - PM2 │ │ │ │
|
|
│ └─────────────────────┘ └─────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Server-Details
|
|
|
|
### LXC 700 - sv-payload (Application Server)
|
|
|
|
| Eigenschaft | Wert |
|
|
|-------------|------|
|
|
| IP | 10.10.181.100 |
|
|
| Öffentlich | 37.24.237.181 (via NAT) |
|
|
| OS | Debian 13 (Trixie) |
|
|
| CPU | 4 Cores |
|
|
| RAM | 4 GB |
|
|
| Disk | 40 GB |
|
|
| Domain | pl.c2sgmbh.de |
|
|
|
|
**Installierte Software:**
|
|
- Node.js 22 LTS (via NodeSource)
|
|
- pnpm (Package Manager)
|
|
- Caddy 2.10.2 (Reverse Proxy mit automatischem SSL)
|
|
- PM2 (Process Manager)
|
|
- Payload CMS 3.x mit Next.js 15.4.7
|
|
|
|
**Dienste:**
|
|
- Caddy läuft als systemd service auf Port 80/443
|
|
- Payload läuft via PM2 auf Port 3000
|
|
|
|
### LXC 701 - sv-postgres (Database Server)
|
|
|
|
| Eigenschaft | Wert |
|
|
|-------------|------|
|
|
| IP | 10.10.181.101 |
|
|
| Öffentlich | Nein (nur intern) |
|
|
| OS | Debian 13 (Trixie) |
|
|
| CPU | 2 Cores |
|
|
| RAM | 2 GB |
|
|
| Disk | 20 GB |
|
|
|
|
**Datenbank:**
|
|
- PostgreSQL 17
|
|
- Database: payload_db
|
|
- User: payload
|
|
- Passwort: Finden55
|
|
- Nur erreichbar von 10.10.181.100
|
|
|
|
## Verzeichnisstruktur auf sv-payload
|
|
|
|
```
|
|
/home/payload/
|
|
├── payload-cms/ # Hauptanwendung
|
|
│ ├── src/
|
|
│ │ ├── collections/
|
|
│ │ │ ├── Users.ts
|
|
│ │ │ ├── Media.ts
|
|
│ │ │ └── Tenants.ts
|
|
│ │ ├── payload.config.ts
|
|
│ │ └── payload-types.ts
|
|
│ ├── .env # Umgebungsvariablen
|
|
│ ├── ecosystem.config.cjs # PM2 Konfiguration
|
|
│ ├── package.json
|
|
│ └── .next/ # Next.js Build Output
|
|
├── logs/
|
|
│ ├── error-0.log
|
|
│ └── out-0.log
|
|
└── ecosystem.config.cjs # PM2 Config (Symlink)
|
|
```
|
|
|
|
## Konfigurationsdateien
|
|
|
|
### .env (/home/payload/payload-cms/.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
|
|
```
|
|
|
|
### Caddyfile (/etc/caddy/Caddyfile)
|
|
|
|
```caddyfile
|
|
{
|
|
email deine-email@c2sgmbh.de
|
|
}
|
|
|
|
pl.c2sgmbh.de {
|
|
reverse_proxy localhost:3000
|
|
|
|
request_body {
|
|
max_size 100MB
|
|
}
|
|
|
|
header {
|
|
X-Content-Type-Options nosniff
|
|
X-Frame-Options SAMEORIGIN
|
|
-Server
|
|
}
|
|
|
|
encode gzip zstd
|
|
}
|
|
```
|
|
|
|
### PM2 Konfiguration (/home/payload/payload-cms/ecosystem.config.cjs)
|
|
|
|
```javascript
|
|
module.exports = {
|
|
apps: [{
|
|
name: 'payload',
|
|
cwd: '/home/payload/payload-cms',
|
|
script: 'pnpm',
|
|
args: 'start',
|
|
env: {
|
|
NODE_ENV: 'production',
|
|
PORT: 3000
|
|
},
|
|
instances: 1,
|
|
autorestart: true,
|
|
max_memory_restart: '1G',
|
|
error_file: '/home/payload/logs/error.log',
|
|
out_file: '/home/payload/logs/out.log'
|
|
}]
|
|
}
|
|
```
|
|
|
|
## Multi-Tenant Konzept
|
|
|
|
Das System verwendet `@payloadcms/plugin-multi-tenant` für die Mandantenfähigkeit.
|
|
|
|
### Tenants (Mandanten)
|
|
|
|
Jeder Tenant repräsentiert eine separate Website:
|
|
|
|
| Tenant | Slug | Domains |
|
|
|--------|------|---------|
|
|
| porwoll.de | porwoll | porwoll.de, www.porwoll.de |
|
|
| Complex Care Solutions GmbH | c2s | complexcaresolutions.de |
|
|
| Gunshin | gunshin | gunshin.de |
|
|
| Zweitmeinung | zweitmeinung | zweitmein.ng |
|
|
|
|
### Datenisolation
|
|
|
|
- Jeder Content (Media, Pages, Posts etc.) gehört zu genau einem Tenant
|
|
- User werden Tenants zugewiesen und sehen nur deren Inhalte
|
|
- Die Domain-Erkennung erfolgt automatisch durch das Plugin
|
|
|
|
### Datenbank-Tabellen
|
|
|
|
```
|
|
tenants - Mandanten-Stammdaten
|
|
tenants_domains - Domain-Zuordnungen
|
|
users_tenants - User-Mandanten-Beziehung (N:M)
|
|
```
|
|
|
|
## Netzwerk & Firewall
|
|
|
|
### UFW Regeln auf sv-payload
|
|
|
|
```bash
|
|
22/tcp ALLOW 10.10.181.0/24 # SSH aus VLAN
|
|
80/tcp ALLOW Anywhere # HTTP (ACME)
|
|
443/tcp ALLOW Anywhere # HTTPS
|
|
```
|
|
|
|
### UFW Regeln auf sv-postgres
|
|
|
|
```bash
|
|
22/tcp ALLOW 10.10.181.0/24 # SSH aus VLAN
|
|
5432/tcp ALLOW 10.10.181.100 # PostgreSQL nur von Payload
|
|
```
|
|
|
|
## DSGVO-Konformität
|
|
|
|
Die Architektur wurde bewusst ohne Cloudflare designed:
|
|
- Keine US-Dienste im Datenpfad für Admin-Zugriffe
|
|
- Direkte öffentliche IP statt Proxy
|
|
- Keine Auftragsverarbeiter-Verträge für CDN nötig
|
|
- Redakteur-IPs und Sessions bleiben in DE
|
|
|
|
## Wichtige Befehle
|
|
|
|
### Payload Management
|
|
|
|
```bash
|
|
# Als payload User
|
|
su - payload
|
|
cd ~/payload-cms
|
|
|
|
# Entwicklung
|
|
pnpm dev
|
|
|
|
# Build für Production
|
|
pnpm build
|
|
|
|
# Migrationen
|
|
pnpm payload migrate:create
|
|
pnpm payload migrate
|
|
|
|
# ImportMap generieren (nach Plugin-Änderungen)
|
|
pnpm payload generate:importmap
|
|
```
|
|
|
|
### PM2 Management
|
|
|
|
```bash
|
|
pm2 status
|
|
pm2 logs payload
|
|
pm2 restart payload
|
|
pm2 stop payload
|
|
pm2 start ecosystem.config.cjs
|
|
```
|
|
|
|
### Caddy Management
|
|
|
|
```bash
|
|
sudo systemctl status caddy
|
|
sudo systemctl restart caddy
|
|
sudo caddy validate --config /etc/caddy/Caddyfile
|
|
```
|
|
|
|
### Datenbank
|
|
|
|
```bash
|
|
# Von sv-payload aus
|
|
PGPASSWORD=Finden55 psql -h 10.10.181.101 -U payload -d payload_db
|
|
|
|
# Tabellen anzeigen
|
|
\dt
|
|
|
|
# Tenants abfragen
|
|
SELECT * FROM tenants;
|
|
SELECT * FROM users_tenants;
|
|
```
|
|
|
|
## Zugriff
|
|
|
|
- **Admin Panel**: https://pl.c2sgmbh.de/admin
|
|
- **API**: https://pl.c2sgmbh.de/api
|
|
- **SSH Payload Server**: ssh root@10.10.181.100 (aus VLAN 181)
|
|
- **SSH Postgres Server**: ssh root@10.10.181.101 (aus VLAN 181)
|