Files
streamdock/docs/docker.md
2026-04-12 22:50:50 +02:00

5.9 KiB

Docker & Deployment

Docker-Image

StreamDock verwendet einen Multi-Stage Build für ein schlankes Produktions-Image.

Build-Stufen

1. Build Stage (golang:1.23-alpine)

  • Kompiliert das Go-Binary mit CGO_ENABLED=0 (statisch gelinkt, keine C-Abhängigkeiten)
  • Flags: -ldflags="-s -w" (ohne Debug-Symbole, kleineres Binary)

2. Runtime Stage (alpine:3.21)

  • Installierte Pakete: ca-certificates, tzdata, ffmpeg, su-exec
  • Image-Größe: ca. 30 MB
  • Enthält: Go-Binary, Web-Assets, Entrypoint-Script

Container-Benutzer & Sicherheit

Prozess-Benutzer

Der Container erstellt einen dedizierten Benutzer streamdock (ohne Root-Rechte):

RUN adduser -D -h /app streamdock

Das Entrypoint-Script (entrypoint.sh) führt folgende Schritte aus:

  1. Setzt Besitzrechte auf die Daten-Verzeichnisse (nötig, da Volumes als root gemountet werden können)
  2. Startet die Anwendung als streamdock-Benutzer via su-exec
#!/bin/sh
chown -R streamdock:streamdock /app/data
exec su-exec streamdock ./streamdock "$@"

Fazit: Die Anwendung selbst läuft als Non-Root-Benutzer innerhalb des Containers. Der Container-Einstiegspunkt benötigt kurzzeitig Root-Rechte für das Setzen der Volume-Berechtigungen.

Rootless Docker

Hinweis: StreamDock verwendet aktuell kein Rootless Docker. Der Docker-Daemon läuft weiterhin mit Root-Rechten. Das ist ein separates Thema und betrifft die Docker-Installation auf dem Host, nicht den Container selbst.

Eine Migration zu Rootless Docker kann die Sicherheit weiter erhöhen, indem auch der Docker-Daemon ohne Root-Privilegien betrieben wird. Dies ist insbesondere für öffentlich erreichbare Systeme empfehlenswert und steht als zukünftige Verbesserung auf der Roadmap.


docker-compose.yml

services:
  streamdock:
    build: .
    image: streamdock:latest
    container_name: streamdock
    restart: unless-stopped
    ports:
      - "8080:8080"
    volumes:
      - ./data/config:/app/data/config
      - ./data/recordings:/app/data/recordings
      - ./data/avatars:/app/data/avatars
    env_file:
      - .env
    networks:
      streamdock_net:
        ipv4_address: 172.23.64.10
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:8080/api/auth/me"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

networks:
  streamdock_net:
    name: streamdock.dockernetwork.local
    driver: bridge
    ipam:
      config:
        - subnet: 172.23.64.0/24
          gateway: 172.23.64.1
          ip_range: 172.23.64.128/25

Volumes

Container-Pfad Host-Pfad Beschreibung
/app/data/config ./data/config SQLite-Datenbank (streamdock.db)
/app/data/recordings ./data/recordings Aufgenommene Audio-/Video-Dateien
/app/data/avatars ./data/avatars Benutzer-Profilbilder

Wichtig: Die Volumes bleiben bei Container-Neustart/Update erhalten. Ein Backup der data/-Verzeichnisse sichert den kompletten Anwendungszustand.


Health Check

Der Container prüft regelmäßig seine eigene Erreichbarkeit:

GET http://localhost:8080/api/auth/me
Parameter Wert
Intervall 30 Sekunden
Timeout 5 Sekunden
Retries 3
Start-Verzögerung 10 Sekunden

Netzwerk

StreamDock erstellt ein eigenes Bridge-Netzwerk:

Eigenschaft Wert
Name streamdock.dockernetwork.local
Treiber bridge
Subnetz 172.23.64.0/24
Gateway 172.23.64.1
Container-IP 172.23.64.10

Deployment mit Reverse Proxy

Für den produktionsnahen Betrieb wird ein Reverse Proxy mit HTTPS empfohlen.

Beispiel: nginx

server {
    listen 443 ssl;
    server_name streamdock.example.com;

    ssl_certificate     /etc/letsencrypt/live/streamdock.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/streamdock.example.com/privkey.pem;

    location / {
        proxy_pass http://172.23.64.10:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Für Streaming/große Dateien
        proxy_buffering off;
        proxy_read_timeout 300s;
    }
}

Beispiel: Traefik (Labels)

services:
  streamdock:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.streamdock.rule=Host(`streamdock.example.com`)"
      - "traefik.http.routers.streamdock.tls.certresolver=letsencrypt"
      - "traefik.http.services.streamdock.loadbalancer.server.port=8080"

Befehle

Container starten

docker compose up -d

Container stoppen

docker compose down

Logs ansehen

docker compose logs -f streamdock

Neu bauen (nach Update)

docker compose build --no-cache
docker compose up -d

Datenbank zurücksetzen

# Container stoppen
docker compose down

# Datenbank löschen
rm data/config/streamdock.db

# Neu starten (DB wird automatisch erstellt)
docker compose up -d

Backup

# Komplettes Backup der Anwendungsdaten
tar -czf streamdock-backup-$(date +%Y%m%d).tar.gz data/

# Nur Datenbank sichern
cp data/config/streamdock.db streamdock-backup-$(date +%Y%m%d).db

Umgebungsvariablen im Container

Variable Standard Beschreibung
STREAMDOCK_HOST 0.0.0.0 Bind-Adresse
STREAMDOCK_PORT 8080 Lausch-Port
STREAMDOCK_DB_PATH /app/data/config/streamdock.db Datenbank-Pfad
STREAMDOCK_RECORDINGS_PATH /app/data/recordings Aufnahme-Pfad
STREAMDOCK_AVATARS_PATH /app/data/avatars Avatar-Pfad

Alle weiteren Variablen: siehe Konfiguration.


Weiter: Benutzerverwaltung