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

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
- Docker Engine (aktuelle Version) und Docker Compose V2, siehe Docker und Docker Compose auf Linux installieren.
- 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.
- Mindestens 20 GB SSD für das System; Videos benötigen zusätzlichen Speicher, alternativ ein S3-kompatibler Objektspeicher.
- Öffentliche IP-Adresse und eine registrierte Domain. HTTPS ist Pflicht, weil die ActivityPub-Federation nur darüber funktioniert.
- DNS-Zugang: Ein A-Record (und optional AAAA für IPv6) muss auf die Server-IP zeigen, bevor Sie Certbot starten.
- 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.
- openssl verfügbar (für die Generierung des
PEERTUBE_SECRET). - 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/peertubeLegen 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/keysVerifizieren: 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/peertubewc -l /opt/peertube/docker-volume/nginx/peertubeVerifizieren: 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 32Legen 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=noSchützen Sie die Datei vor fremdem Zugriff:
chmod 600 /opt/peertube/.envVerifizieren: 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
| Parameter | Wert |
|---|---|
| Image (PeerTube) | chocobozzz/peertube:v8.3.1 (alternativ production) |
| Webserver-Image | chocobozzz/peertube-webserver:latest (einziger Release-Tag) |
| Datenbank | postgres:17-alpine |
| Cache | redis:8-alpine |
| Port HTTP/HTTPS | 80, 443 (Nginx) |
| Port RTMP | 1935 (PeerTube direkt) |
| Architektur | linux/amd64, linux/arm64 |
| Lizenz | AGPL-3.0 |
| Volume (Host-Pfad) | Zweck |
|---|---|
| ./docker-volume/data | Videos, Thumbnails, Avatare |
| ./docker-volume/config | production.yaml (PeerTube-Konfiguration) |
| ./docker-volume/db | PostgreSQL-Datenbankdateien |
| ./docker-volume/redis | Redis-Persistenz |
| ./docker-volume/nginx/peertube | Nginx-Konfigurationstemplate |
| ./docker-volume/certbot/conf | Let's-Encrypt-Zertifikate |
| ./docker-volume/nginx-logs | Nginx-Zugriffs- und Fehlerprotokolle |
| ./docker-volume/opendkim/keys | DKIM-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.deVerifizieren: 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 -dDer erste Start lädt mehrere Gigabyte Images und legt die Datenbank an. Beobachten Sie die Logs:
docker compose logs -f peertubeWarten 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 UpTesten Sie zusätzlich den HTTPS-Zugriff:
curl -I https://video.meinedomain.deErwartet 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 rootDie Ausgabe sieht etwa so aus:
# User root created.
# User password: AbCdEf123456XyZMelden 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 rootRichten Sie in der Administration anschließend ein:
- Instanzname und Beschreibung in der Instanzkonfiguration.
- Registrierungsmodus: offen, mit Genehmigung oder geschlossen. Für Firmeninstanzen ist „geschlossen“ üblich.
- Federation: anderen Instanzen folgen oder eingehende Follows genehmigen.
- DKIM: Der Postfix-Container erzeugt den Schlüssel selbst. Den DNS-TXT-Eintrag (Selektor
peertube) zeigtcat ./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.jsFür den Backup-Prozess sind drei Bereiche relevant:
- Datenbank: per
pg_dumpoder bei gestopptem Stack./docker-volume/dbsichern (Anleitung: PostgreSQL pg_dump und pg_restore). - Videodaten:
./docker-volume/data, kann sehr groß werden. - Konfiguration:
./docker-volume/configund.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 serverVersionTroubleshooting / Typische Fehler
- Webserver-Container startet nicht, Fehler zum Template:
docker-volume/nginx/peertubefehlt oder ist ein Verzeichnis. Verzeichnis entfernen und die Datei wie in Schritt 2 laden. - Webserver startet nicht (Zertifikat-Fehler): Das Zertifikat aus Schritt 5 fehlt unter
./docker-volume/certbot/conf/live/. - Docker-Netz wird nicht angelegt (IPv6-Fehler): Docker aktualisieren oder IPv6 im Daemon aktivieren, siehe Schritt 1. Kollidiert das Subnetz
172.18.0.0/16mit einem vorhandenen Netz, passen Sie Subnetz, feste IP undPEERTUBE_TRUST_PROXYgemeinsam an. - Anmeldungen brechen ab:
PEERTUBE_SECRETfehlt 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. - Falsche Client-IPs, Rate-Limits greifen falsch:
PEERTUBE_TRUST_PROXYfehlt das Subnetz172.18.0.0/16. - RTMP-Livestreaming schlägt fehl: Port 1935 ist durch die Firewall blockiert. Freigeben mit
sudo ufw allow 1935/tcp. - PostgreSQL meldet falsche Verzeichnisrechte: Bei einer neuen Installation
./docker-volume/dbleeren und mitchmod 700neu anlegen, PostgreSQL initialisiert es selbst. Bei bestehenden Daten nie löschen, sondern Rechte korrigieren. - 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
- Docker und Docker Compose auf Linux installieren: die Self-Hosting-Grundlage
- VPS absichern und härten: UFW, SSH-Keys und Fail2Ban
- MinIO S3 selbst hosten mit Docker und Traefik
- PostgreSQL pg_dump und pg_restore: Backup und Migration
- 3-2-1-Backup-Strategie praktisch umsetzen
- Jellyfin mit Docker: eigener Media-Server ohne Abo
Offizielle Quellen: PeerTube Docker-Installationsdokumentation (docs.joinpeertube.org) sowie das PeerTube GitHub-Repository (Chocobozzz/PeerTube).


