Architektur
Inhalt
Überblick
ITSWEBER Play wird als einzelner Docker-Container ausgeliefert, der genau einen Port (3000) exponiert. Eine Nginx-Instanz innerhalb des Containers multiplext eingehende Anfragen und leitet sie an den jeweils zuständigen internen Service weiter. Docker-Compose-Orchestrierung oder ein Container-Netzwerk werden nicht benötigt — alles läuft in einem Prozessbaum, der von s6-overlay verwaltet wird.
Container-Topologie
┌─────────────────────────────────────────┐
│ itsweber-play:3000 │
│ ┌──────────────────────────────────┐ │
│ │ Nginx :80 (intern) │ │
│ └──┬──────────────┬────────────────┘ │
│ │ │ │
│ ┌──▼──┐ ┌───▼────┐ │
│ │ Web │ │ API │ │
│ │:3100│ │ :4000 │ │
│ └─────┘ └───┬────┘ │
│ │ │
│ ┌─────┐ ┌──────┐ │ ┌──────┐ │
│ │Redis│ │MinIO │ │ │Pgsql │ │
│ │:6379│ │:9000 │ │ │:5432 │ │
│ └─────┘ └──────┘ │ └──────┘ │
│ ┌───▼────┐ │
│ │ Worker │ │
│ └────────┘ │
└─────────────────────────────────────────┘
Die gesamte Inter-Service-Kommunikation läuft über 127.0.0.1. Das Web-Frontend ist eine Next.js-15-App-Router-Anwendung. Das API ist ein Fastify-Server, der tRPC-Prozeduren und Better-Auth-Endpunkte bereitstellt. Der Worker ist ein BullMQ-Consumer, der FFmpeg- und yt-dlp-Jobs ausführt.
s6-overlay Startreihenfolge
s6-overlay steuert die Startreihenfolge und startet abgestürzte Services automatisch neu:
postgres-init— Legt das Postgres-Datenverzeichnis und den Cluster an, falls noch nicht vorhanden.postgres— Startet den Postgres-Server auf:5432.migrate— Führtprisma migrate deploygegen die lokale Postgres-Instanz aus. Blockiert bis zum Abschluss.minio— Startet den MinIO-Server auf:9000und legt Standard-Buckets an.redis— Startet den Redis-Server auf:6379.api— Startet den Fastify-API-Server auf:4000.worker— Startet den BullMQ-Worker-Prozess.web— Startet den Next.js-Server auf:3100.nginx— Startet Nginx auf:80(intern), gemappt auf den exponierten Container-Port3000.
Services
| Service | Interner Port | Zweck |
|---|---|---|
| Nginx | 80 | Request-Multiplexer; leitet /api/*, /auth/*, /trpc/* ans API, alles andere ans Web |
| Web (Next.js) | 3100 | SSR-Frontend, Studio, Admin-Panel |
| API (Fastify) | 4000 | tRPC, Better Auth, Upload-Endpunkt, HLS-Signed-URLs |
| Worker (BullMQ) | — | FFmpeg-Transcodierung, yt-dlp-Import, Thumbnail-Extraktion |
| Postgres 16 | 5432 | Primäre Datenbank (Prisma ORM) |
| Redis 7 | 6379 | BullMQ-Job-Queues, Session-Cache, Pub/Sub für Live-Fortschritt |
| MinIO | 9000 | S3-kompatibler Objektspeicher für Videos, Thumbnails, Assets |
Datenflüsse
Upload
Browser → Web (tus-Chunk) → API → MinIO (raw)
→ Worker (enqueue)
Worker → MinIO (raw pullen) → FFmpeg → HLS-Segmente → MinIO (play-videos/)
Worker → Redis Pub/Sub (Fortschrittsereignisse)
API → SSE → Browser (Live-Fortschrittsbalken)
Externer Import (yt-dlp)
- Nutzer gibt eine URL im Studio ein.
- API legt einen Video-Datensatz mit
status=importingan und stellt einen Job in die Queue. - Worker lädt die Quelle via
yt-dlpherunter und transcodiert mit FFmpeg. - Das Video wird sichtbar. Die Standard-Sichtbarkeit nach dem Import ist
private— der Nutzer muss es explizit veröffentlichen.
Auth
Browser → POST /auth/sign-in → Better Auth → Session-Cookie (HTTP-only, SameSite=Lax)
Browser → GET /trpc/* → API liest Cookie → validiert Session → gibt Daten zurück
Theme-Update
Admin speichert Token-Änderung → API schreibt in DB → SSE-Ereignis wird gesendet
Browser empfängt SSE → ersetzt <style id="theme-vars"> → Live-Update, kein Reload
Speicher-Layout
MinIO organisiert die Daten in folgenden Buckets:
| Bucket | Inhalt |
|---|---|
play-raw |
Original-Videodateien nach dem Upload (verbleiben bis Transcodierung abgeschlossen) |
play-videos |
HLS-Segmente und Playlisten (.m3u8, .ts) |
play-thumbs |
Automatisch generierte Thumbnail-Kandidaten und ausgewählte Thumbnails |
play-assets |
Logo, Favicon, Kanal-Avatare, Banner |
Alle Buckets sind privat. Das API generiert vorzeichenbehaftete URLs (Pre-signed URLs) für Wiedergabe und Asset-Auslieferung.
Monorepo-Pakete
| Paket | Zweck |
|---|---|
apps/web |
Next.js-15-App-Router-Frontend |
apps/api |
Fastify + tRPC + Better Auth Backend |
apps/worker |
BullMQ + FFmpeg + yt-dlp Video-Pipeline |
apps/remotion |
Demo-Video-Rendering (Remotion) |
packages/db |
Prisma-Schema und generierter Client |
packages/theme |
6-Ebenen-Token-System und Live-Editor-Komponenten |
packages/shared |
Gemeinsam genutzte TypeScript-Typen und Enums |
packages/storage |
MinIO-Client-Wrapper |
docker/all-in-one |
Dockerfile, s6-overlay-Service-Definitionen, Nginx-Konfiguration |
docker/unraid |
Unraid Community Apps XML-Template |