Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Cloud / Hosting 05.07.2026 · 9 min Lesezeit

PeerTube mit Docker installieren: Dezentrale, föderierte Videoplattform selbst hosten

PeerTube 8.3.1 mit Docker Compose selbst hosten: föderierte Videoplattform ohne Werbung und Tracking, mit HTTPS über Let's Encrypt, E-Mail per Postfix, RTMP-Livestreaming, Update und Backup.

Geprüft am 30.09.2026 · für peertube 8.3.1

WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Videokamera auf Stativ in einem Seminarraum und ein kleiner Server im Regal, verbunden durch Lichtlinien als Sinnbild für eine selbst gehostete Videoplattform

PeerTube ist eine föderierte Open-Source-Videoplattform auf Basis des ActivityPub-Protokolls, das auch Mastodon und das übrige Fediverse nutzen. Entwickelt wird sie von der französischen Organisation Framasoft. Bildungseinrichtungen, Vereine und Unternehmen hosten damit Videos ohne Werbung, Tracking und zentrale Plattform. Diese Anleitung führt Sie durch die Installation mit Docker Compose auf einem Linux-Server, angelehnt an die offizielle Docker-Anleitung des Projekts.

Voraussetzungen

  1. Docker Engine (aktuelle Version) und Docker Compose V2, siehe Docker und Docker Compose auf Linux installieren.
  2. Linux-Server oder VPS (Ubuntu 22.04/24.04 oder Debian 12 empfohlen) mit mindestens 2 vCPU und 2 GB RAM (4 GB empfohlen, Transkodierung braucht CPU), x86_64 oder ARM64.
  3. Mindestens 20 GB SSD für das System; Videos benötigen zusätzlichen Speicher, alternativ ein S3-kompatibler Objektspeicher.
  4. Öffentliche IP-Adresse und eine registrierte Domain. HTTPS ist Pflicht, weil die ActivityPub-Federation nur darüber funktioniert.
  5. DNS-Zugang: Ein A-Record (und optional AAAA für IPv6) muss auf die Server-IP zeigen, bevor Sie Certbot starten.
  6. Eingehende Firewall-Freigaben für Port 80, 443 und optional 1935 (RTMP-Livestreaming). UFW konfigurieren Sie wie in VPS absichern und härten mit UFW, SSH-Keys und Fail2Ban.
  7. openssl verfügbar (für die Generierung des PEERTUBE_SECRET).
  8. Ein Docker-Netz mit IPv6-Unterstützung (die offizielle Compose-Datei legt es selbst an, siehe Schritt 1).

Schritt 1: IPv6 für Docker aktivieren und Projektordner anlegen

Die offizielle Compose-Datei legt ein eigenes Netz mit enable_ipv6: true und festen Subnetzen an. Für solche benutzerdefinierten Netze ist laut Docker-Dokumentation keine Änderung an /etc/docker/daemon.json nötig. Nur wenn docker compose up auf einer älteren Docker-Version mit einem IPv6-Fehler abbricht, aktualisieren Sie Docker oder setzen dort "ipv6": true und "fixed-cidr-v6" (erfordert einen Neustart des Docker-Dienstes und damit aller Container).

Legen Sie den Projektordner an, /opt/peertube ist für Server üblich:

sudo mkdir -p /opt/peertube
sudo chown $USER:$USER /opt/peertube
cd /opt/peertube

Legen Sie die Unterordner für Volumes und das Nginx-Template an:

mkdir -p docker-volume/data \
  docker-volume/config \
  docker-volume/db \
  docker-volume/redis \
  docker-volume/nginx \
  docker-volume/certbot/conf \
  docker-volume/nginx-logs \
  docker-volume/opendkim/keys

Verifizieren: ls /opt/peertube/docker-volume/ zeigt certbot, config, data, db, nginx, nginx-logs, opendkim und redis.

Schritt 2: Nginx-Konfigurationstemplate herunterladen

Das Nginx-Template ist nicht im Image enthalten. Laden Sie es aus dem offiziellen Repository als Datei docker-volume/nginx/peertube herunter, die Compose-Datei bindet genau diese Datei ein. Der Container ersetzt darin ${WEBSERVER_HOST} und ${PEERTUBE_HOST} aus der .env.

curl -fsSL \
  https://raw.githubusercontent.com/Chocobozzz/PeerTube/master/support/nginx/peertube \
  -o /opt/peertube/docker-volume/nginx/peertube
wc -l /opt/peertube/docker-volume/nginx/peertube

Verifizieren: wc -l meldet rund 260 Zeilen, und ls -l docker-volume/nginx/ zeigt peertube als Datei, nicht als Verzeichnis. Fehlt die Datei, legt Docker beim Start ein leeres Verzeichnis an und Nginx startet nicht.

Schritt 3: .env-Datei erstellen

Alle Einstellungen stehen in der .env im Projektordner. Die vollständige Vorlage liefert das Projekt unter support/docker/production/.env. Erzeugen Sie zuerst ein Secret:

openssl rand -hex 32

Legen Sie dann die .env an:

nano /opt/peertube/.env
# === PostgreSQL ===
POSTGRES_USER=peertube_user
POSTGRES_PASSWORD=IHR-DB-PASSWORT
POSTGRES_DB=peertube

# === PeerTube Datenbank ===
PEERTUBE_DB_USERNAME=${POSTGRES_USER}
PEERTUBE_DB_PASSWORD=${POSTGRES_PASSWORD}
PEERTUBE_DB_HOSTNAME=postgres
PEERTUBE_DB_SSL=false

# === PeerTube Kernkonfiguration ===
# ACHTUNG: PEERTUBE_WEBSERVER_HOSTNAME ist nach dem ersten Start UNVERAENDERLICH!
PEERTUBE_WEBSERVER_HOSTNAME=video.meinedomain.de

# Secret generieren mit: openssl rand -hex 32
PEERTUBE_SECRET=AUSGABE_VON_OPENSSL_RAND_HEX_32

# Vertrauenswuerdige Proxy-IPs (Nginx-Subnetz muss enthalten sein)
PEERTUBE_TRUST_PROXY=["127.0.0.1","loopback","172.18.0.0/16"]

# === Administrator ===
PEERTUBE_ADMIN_EMAIL=admin@meinedomain.de

# === SMTP / Postfix ===
PEERTUBE_SMTP_HOSTNAME=postfix
PEERTUBE_SMTP_PORT=25
PEERTUBE_SMTP_FROM=noreply@meinedomain.de
PEERTUBE_SMTP_TLS=false

# === Postfix / DKIM (optional) ===
POSTFIX_myhostname=meinedomain.de
OPENDKIM_DOMAINS=meinedomain.de=peertube
OPENDKIM_RequireSafeKeys=no

Schützen Sie die Datei vor fremdem Zugriff:

chmod 600 /opt/peertube/.env

Verifizieren: grep PEERTUBE_SECRET /opt/peertube/.env zeigt einen 64-stelligen Hex-Wert, PEERTUBE_WEBSERVER_HOSTNAME enthält Ihre Domain ohne https://, und stat -c %a /opt/peertube/.env liefert 600.

Schritt 4: compose.yaml erstellen

Legen Sie die Compose-Datei im Projektordner an. Sie entspricht der offiziellen Datei, nur das PeerTube-Image ist auf eine Version festgelegt. Der Stack verwendet sieben Services: peertube, postgres, redis, webserver (Nginx), postfix, certbot und webserver-reloader. Der webserver-reloader lädt Nginx alle 6 Stunden neu, damit erneuerte Zertifikate greifen.

Eckdaten auf einen Blick

ParameterWert
Image (PeerTube)chocobozzz/peertube:v8.3.1 (alternativ production)
Webserver-Imagechocobozzz/peertube-webserver:latest (einziger Release-Tag)
Datenbankpostgres:17-alpine
Cacheredis:8-alpine
Port HTTP/HTTPS80, 443 (Nginx)
Port RTMP1935 (PeerTube direkt)
Architekturlinux/amd64, linux/arm64
LizenzAGPL-3.0
Volume (Host-Pfad)Zweck
./docker-volume/dataVideos, Thumbnails, Avatare
./docker-volume/configproduction.yaml (PeerTube-Konfiguration)
./docker-volume/dbPostgreSQL-Datenbankdateien
./docker-volume/redisRedis-Persistenz
./docker-volume/nginx/peertubeNginx-Konfigurationstemplate
./docker-volume/certbot/confLet's-Encrypt-Zertifikate
./docker-volume/nginx-logsNginx-Zugriffs- und Fehlerprotokolle
./docker-volume/opendkim/keysDKIM-Schlüsseldateien für E-Mail
services:
  webserver:
    image: chocobozzz/peertube-webserver:latest
    env_file:
      - .env
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - type: bind
        source: ./docker-volume/nginx/peertube
        target: /etc/nginx/conf.d/peertube.template
      - assets:/var/www/peertube/peertube-latest/client/dist:ro
      - ./docker-volume/data:/var/www/peertube/storage
      - certbot-www:/var/www/certbot
      - ./docker-volume/certbot/conf:/etc/letsencrypt
      - ./docker-volume/nginx-logs:/var/log/nginx
    depends_on:
      - peertube
    restart: "always"

  certbot:
    container_name: certbot
    image: certbot/certbot
    volumes:
      - ./docker-volume/certbot/conf:/etc/letsencrypt
      - certbot-www:/var/www/certbot
    restart: unless-stopped
    entrypoint: /bin/sh -c "trap exit TERM; while :; do certbot renew --webroot -w /var/www/certbot; sleep 12h & wait $${!}; done;"
    depends_on:
      - webserver

  webserver-reloader:
    image: alpine:latest
    command: >
      sh -c "trap exit TERM;
      while :; do
      sleep 21600 & wait $$!;
      echo 'Sending reload signal to webserver...';
      kill -HUP 1;
      done"
    pid: "service:webserver"
    depends_on:
      - webserver
    restart: "always"

  peertube:
    image: chocobozzz/peertube:v8.3.1
    networks:
      default:
        ipv4_address: 172.18.0.42
        ipv6_address: fdab:e4b3:21a2:ef1b::42
    env_file:
      - .env
    ports:
      - "1935:1935" # nur fuer Livestreams, sonst auskommentieren
    volumes:
      - assets:/app/client/dist
      - ./docker-volume/data:/data
      - ./docker-volume/config:/config
    depends_on:
      - postgres
      - redis
      - postfix
    restart: "always"

  postgres:
    image: postgres:17-alpine
    env_file:
      - .env
    volumes:
      - ./docker-volume/db:/var/lib/postgresql/data
    restart: "always"

  redis:
    image: redis:8-alpine
    volumes:
      - ./docker-volume/redis:/data
    restart: "always"

  postfix:
    image: mwader/postfix-relay
    env_file:
      - .env
    volumes:
      - ./docker-volume/opendkim/keys:/etc/opendkim/keys
    restart: "always"

networks:
  default:
    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: 172.18.0.0/16
        - subnet: fdab:e4b3:21a2:ef1b::/64

volumes:
  assets:
  certbot-www:

Verifizieren: docker compose -f /opt/peertube/compose.yaml config --quiet endet ohne Ausgabe. Fehlermeldungen deuten auf Einrückungsfehler oder fehlende Variablen hin.

Schritt 5: Erstes TLS-Zertifikat ausstellen

Nginx startet ohne Zertifikat nicht. Holen Sie deshalb vor dem ersten Start ein Let's-Encrypt-Zertifikat im Standalone-Modus. Der A-Record muss bereits auf die Server-IP zeigen, Port 80 muss frei und in der Firewall offen sein:

cd /opt/peertube

# Standalone-Modus: certbot belegt kurz Port 80 selbst
docker run --rm \
  -v /opt/peertube/docker-volume/certbot/conf:/etc/letsencrypt \
  -p 80:80 \
  certbot/certbot certonly \
  --standalone \
  --email admin@meinedomain.de \
  --agree-tos \
  --no-eff-email \
  -d video.meinedomain.de

Verifizieren: Das Zertifikat liegt unter /opt/peertube/docker-volume/certbot/conf/live/video.meinedomain.de/fullchain.pem:

ls -la /opt/peertube/docker-volume/certbot/conf/live/video.meinedomain.de/

Schritt 6: Stack starten

Starten Sie alle sieben Container:

cd /opt/peertube
docker compose up -d

Der erste Start lädt mehrere Gigabyte Images und legt die Datenbank an. Beobachten Sie die Logs:

docker compose logs -f peertube

Warten Sie, bis keine neuen Meldungen mehr erscheinen und keine Fehler auftauchen.

Verifizieren: docker compose ps zeigt alle sieben Services als Up:

docker compose ps
# Erwartete Ausgabe (gekürzt):
# NAME                            STATUS
# peertube-webserver-1            Up
# peertube-certbot-1              Up
# peertube-webserver-reloader-1   Up
# peertube-peertube-1             Up
# peertube-postgres-1             Up
# peertube-redis-1                Up
# peertube-postfix-1              Up

Testen Sie zusätzlich den HTTPS-Zugriff:

curl -I https://video.meinedomain.de

Erwartet ist HTTP/2 200 oder eine Weiterleitung auf die Startseite.

Schritt 7: Admin-Passwort abrufen und Ersteinrichtung

PeerTube erzeugt beim ersten Start ein zufälliges Passwort für den Benutzer root und schreibt es in die Logs:

docker compose logs peertube | grep -A1 root

Die Ausgabe sieht etwa so aus:

# User root created.
# User password: AbCdEf123456XyZ

Melden Sie sich unter https://video.meinedomain.de mit root und diesem Passwort an und ändern Sie es sofort in den Kontoeinstellungen. Zum Zurücksetzen dient:

docker compose exec -u peertube peertube npm run reset-password -- -u root

Richten Sie in der Administration anschließend ein:

  1. Instanzname und Beschreibung in der Instanzkonfiguration.
  2. Registrierungsmodus: offen, mit Genehmigung oder geschlossen. Für Firmeninstanzen ist „geschlossen“ üblich.
  3. Federation: anderen Instanzen folgen oder eingehende Follows genehmigen.
  4. DKIM: Der Postfix-Container erzeugt den Schlüssel selbst. Den DNS-TXT-Eintrag (Selektor peertube) zeigt cat ./docker-volume/opendkim/keys/*/*.txt.

Verifizieren: curl -s https://video.meinedomain.de/api/v1/config | grep -o '"serverVersion":"[^"]*"' liefert 8.3.1, und die Anmeldung als root mit dem neuen Passwort gelingt.

Schritt 8: Updates und Backup

Lesen Sie vor jedem Update die IMPORTANT NOTES im Changelog. Ab 8.3.0 verlangt PeerTube PostgreSQL 14 oder neuer und nach dem Update ein einmaliges Migrationsskript. Tragen Sie den neuen Tag in der compose.yaml ein und gehen Sie wie in der offiziellen Anleitung vor. down -v entfernt dabei nur die internen Volumes assets und certbot-www mit den statischen Client-Dateien, Ihre Daten liegen in docker-volume/:

cd /opt/peertube
docker compose pull
docker compose down -v
mv docker-volume/nginx/peertube docker-volume/nginx/peertube.bak
curl -fsSL https://raw.githubusercontent.com/Chocobozzz/PeerTube/master/support/nginx/peertube -o docker-volume/nginx/peertube
docker compose up -d
# nur beim Update auf 8.3.x, nach "Migrations finished" im Log:
docker compose exec -u peertube peertube node dist/scripts/migrations/peertube-8.3.js

Für den Backup-Prozess sind drei Bereiche relevant:

  1. Datenbank: per pg_dump oder bei gestopptem Stack ./docker-volume/db sichern (Anleitung: PostgreSQL pg_dump und pg_restore).
  2. Videodaten: ./docker-volume/data, kann sehr groß werden.
  3. Konfiguration: ./docker-volume/config und .env-Datei.

Zur Backup-Strategie siehe 3-2-1-Backup-Strategie umsetzen.

Verifizieren: Nach dem Update meldet die API die neue Version, und docker compose ps zeigt alle Dienste als Up:

curl -s https://video.meinedomain.de/api/v1/config | grep serverVersion

Troubleshooting / Typische Fehler

  1. Webserver-Container startet nicht, Fehler zum Template: docker-volume/nginx/peertube fehlt oder ist ein Verzeichnis. Verzeichnis entfernen und die Datei wie in Schritt 2 laden.
  2. Webserver startet nicht (Zertifikat-Fehler): Das Zertifikat aus Schritt 5 fehlt unter ./docker-volume/certbot/conf/live/.
  3. Docker-Netz wird nicht angelegt (IPv6-Fehler): Docker aktualisieren oder IPv6 im Daemon aktivieren, siehe Schritt 1. Kollidiert das Subnetz 172.18.0.0/16 mit einem vorhandenen Netz, passen Sie Subnetz, feste IP und PEERTUBE_TRUST_PROXY gemeinsam an.
  4. Anmeldungen brechen ab: PEERTUBE_SECRET fehlt oder wurde nach dem ersten Start geändert. Ein neues Secret beendet alle Sitzungen. Setzen Sie es einmalig und ändern Sie es danach nicht mehr.
  5. Falsche Client-IPs, Rate-Limits greifen falsch: PEERTUBE_TRUST_PROXY fehlt das Subnetz 172.18.0.0/16.
  6. RTMP-Livestreaming schlägt fehl: Port 1935 ist durch die Firewall blockiert. Freigeben mit sudo ufw allow 1935/tcp.
  7. PostgreSQL meldet falsche Verzeichnisrechte: Bei einer neuen Installation ./docker-volume/db leeren und mit chmod 700 neu anlegen, PostgreSQL initialisiert es selbst. Bei bestehenden Daten nie löschen, sondern Rechte korrigieren.
  8. Domain nachträglich ändern: Technisch nicht unterstützt. PeerTube speichert die Domain beim ersten Start in der Datenbank. Einzige Option ist eine Neuinstallation mit neuer Domain.

Häufige Fragen

Kann ich PeerTube lokal ohne öffentliche Domain testen?

Ja. Die offizielle .env nennt dafür PEERTUBE_WEBSERVER_HOSTNAME=peertube.localhost, PEERTUBE_WEBSERVER_PORT=9000 und PEERTUBE_WEBSERVER_HTTPS=false, Webserver und Certbot kommentieren Sie aus. Binden Sie Port 9000 dabei an 127.0.0.1. Für den Produktivbetrieb ist HTTPS Pflicht.

Wie aktualisiere ich PeerTube auf eine neue Version?

Backup anlegen, Changelog lesen, Tag in der compose.yaml anpassen und wie in Schritt 8 vorgehen. Die Datenbank-Migrationen laufen beim Start automatisch.

Wie konfiguriere ich Federation mit anderen Instanzen?

In der Administration unter Federation folgen Sie anderen Instanzen, deren Videos dann in Ihrer Instanz erscheinen. Ob eingehende Follows automatisch angenommen werden, legen Sie in der Konfiguration fest.

Kann ich PeerTube auf einem Raspberry Pi 5 betreiben?

Ja, mit 64-Bit-Betriebssystem (Image für linux/arm64). Die Transkodierung ist dort langsam.

Wie groß ist der Speicherbedarf für Videos?

Jedes Video liegt in mehreren Auflösungen vor, der Bedarf wächst schnell auf Hunderte Gigabyte. Planen Sie ./docker-volume/data großzügig oder nutzen Sie einen S3-kompatiblen Objektspeicher über die PEERTUBE_OBJECT_STORAGE_*-Variablen, siehe MinIO S3 selbst hosten mit Docker.

Was bedeutet P2P-Streaming in der Praxis?

Sehen mehrere Zuschauer ein HLS-Video gleichzeitig, tauschen ihre Browser Videosegmente per WebRTC untereinander aus und entlasten den Server. Bei wenigen Zuschauern ist der Effekt gering. WebTorrent nutzt der Player seit Version 6 nicht mehr.

Fazit

Der Stack aus sieben Containern trennt Nginx, Certbot, Datenbank, Cache und E-Mail sauber. Die typischen Fallstricke: Die Domain ist nach dem ersten Start fest, PEERTUBE_SECRET muss vorher gesetzt sein, das Nginx-Template müssen Sie als Datei herunterladen, und Updates verlangen einen Blick in den Changelog.

Weiterführende Anleitungen und Quellen

  1. Docker und Docker Compose auf Linux installieren: die Self-Hosting-Grundlage
  2. VPS absichern und härten: UFW, SSH-Keys und Fail2Ban
  3. MinIO S3 selbst hosten mit Docker und Traefik
  4. PostgreSQL pg_dump und pg_restore: Backup und Migration
  5. 3-2-1-Backup-Strategie praktisch umsetzen
  6. Jellyfin mit Docker: eigener Media-Server ohne Abo

Offizielle Quellen: PeerTube Docker-Installationsdokumentation (docs.joinpeertube.org) sowie das PeerTube GitHub-Repository (Chocobozzz/PeerTube).

Passende News auf S-EDV

  1. FFmpeg PixelSmash: Kritische Sicherheitslücke in weit verbreitetem Video-Decoder
  2. nginx 1.31.2 schließt kritische Lücken in HTTP/3, gRPC und Charset Modul