Das Homelab meistern: Gitea & Jellyfin auf der Synology über Cloudflare Tunnel

Einführung

Das Self-Hosting einer privaten Git-Instanz und eines leistungsstarken Medienservers auf einer Synology NAS ist der ultimative „Power-User”-Schritt. Durch den Einsatz von Cloudflare Tunnels können wir diese Dienste dem Internet zugänglich machen, ohne Firewall-Ports zu öffnen, und gleichzeitig unseren internen Datenverkehr sicher und abgeschottet halten. Dieser Ansatz bietet Sicherheit auf Unternehmensniveau mit Zero-Trust-Architektur und dabei den Komfort des Fernzugriffs von überall auf der Welt.

In diesem Leitfaden richten wir Folgendes ein:

  • Gitea: Ein leichtgewichtiger, selbst gehosteter Git-Dienst
  • Jellyfin: Ein Open-Source-Medienserver für deine persönliche Bibliothek
  • Cloudflare Tunnel: Sicherer Zugang ohne Portweiterleitung

1. Die Architektur

Unser Setup basiert auf einem einzelnen Cloudflare-Tunnel-Container, der als sicheres Gateway für alle unsere Dienste fungiert. So funktioniert es:

  • Docker Bridge Network: Wir verwenden ein dediziertes Netzwerk (app_network), das es dem Tunnel-Container ermöglicht, mit Gitea und Jellyfin über Containernamen als DNS-Einträge zu kommunizieren.
  • Keine Portweiterleitung: Der gesamte Datenverkehr fließt über Cloudflares globales Netzwerk, wodurch es nicht nötig ist, die eigene IP preiszugeben oder Router-Ports zu öffnen.
  • Dienst-Isolation: Jeder Dienst läuft in seinem eigenen Container mit klar definierten Netzwerkgrenzen.

2. Die vollständige Docker-Compose-Konfiguration

Diese Konfiguration orchestriert alle drei Dienste: Gitea (Git-Server), Jellyfin (Medienserver) und den Cloudflare Tunnel für sicheren externen Zugriff.

Speichere dies als docker-compose.yml auf deiner Synology:

version: "3.9"

services:
  # --- Gitea (Git Service) ---
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    restart: always
    networks:
      - app_network
    ports:
      - "3000:3000"   # Web UI
      - "2222:2222"   # SSH (use non-standard port to avoid conflicts)
    environment:
      - USER_UID=1026          # Match your Synology user UID
      - USER_GID=100           # Match your Synology user GID
      - GITEA__server__DOMAIN=gitea.yourdomain.com
      - GITEA__server__SSH_DOMAIN=git.yourdomain.com
      - GITEA__server__ROOT_URL=https://gitea.yourdomain.com/
      - GITEA__server__START_SSH_SERVER=true
      - GITEA__server__SSH_PORT=2222
    volumes:
      - /volume1/docker/gitea:/data

  # --- Jellyfin (Media Server) ---
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    restart: unless-stopped
    networks:
      - app_network
    environment:
      - JELLYFIN_DATA_DIR=/config
      - NVIDIA_VISIBLE_DEVICES=all  # For NVIDIA GPU transcoding (optional)
    volumes:
      - /volume1/docker/jellyfin/config:/config
      - /volume1/media/video/:/media
    ports:
      - "8096:8096"

  # --- Cloudflare Tunnel ---
  tunnel:
    image: cloudflare/cloudflared:latest
    container_name: unified-tunnel
    restart: unless-stopped
    networks:
      - app_network
    command: tunnel run
    environment:
      - TUNNEL_TOKEN=${YOUR_TUNNEL_TOKEN}  # Replace with your actual token

networks:
  app_network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.24.0.0/16

Wichtige Hinweise:

  • Ersetze ${YOUR_TUNNEL_TOKEN} durch dein tatsächliches Cloudflare-Tunnel-Token (erhältlich über das Cloudflare Zero Trust Dashboard)
  • Passe USER_UID und USER_GID an deinen Synology-Benutzer an (führe id <benutzername> per SSH aus, um die Werte zu ermitteln)
  • Aktualisiere die Volume-Pfade entsprechend deiner Synology-Verzeichnisstruktur

3. Cloudflare-Tunnel-Konfiguration

Um externen Datenverkehr zu deinen Diensten zu leiten, konfiguriere Folgendes in deinem Cloudflare Zero Trust Dashboard (unter Networks > Connectors).

Konfiguration öffentlicher Hostnamen

Für jeden Tunnel musst du öffentliche Hostnamen (Anwendungsrouten) hinzufügen. Verwende die folgende Konfiguration:

SubdomainDiensttypInterne URLHinweise
gitea.yourdomain.comHTTPhttp://gitea:3000Gitea Web-UI
git.yourdomain.comTCPtcp://gitea:2222Git SSH (erforderlich für git push/pull)
jelly.yourdomain.comHTTPhttp://jellyfin:8096Jellyfin Medienbibliothek
internal.yourdomain.comHTTPShttps://192.168.50.2:5001Synology DSM (aktiviere „No TLS Verify”)

Warum separate Subdomains für Gitea? Cloudflare Tunnels können pro Subdomain nur eine Dienst-/Port-Kombination routen. Da Gitea zwei verschiedene Dienste hat (Web-UI auf Port 3000 und SSH auf Port 2222), benötigen wir separate Subdomains: gitea.yourdomain.com für das Webinterface und git.yourdomain.com für SSH/Git-Operationen.

Wichtige Konfigurationsschritte:

  1. Tunnel erstellen: Erstelle im Cloudflare Zero Trust Dashboard einen neuen Tunnel und kopiere das Tunnel-Token
  2. Öffentliche Hostnamen hinzufügen: Füge für jede obige Subdomain einen öffentlichen Hostnamen mit dem entsprechenden Diensttyp und der URL hinzu
  3. TCP-Dienst für SSH: Der Eintrag git.yourdomain.com muss den TCP-Typ verwenden (nicht HTTP), um „bad handshake”-Fehler bei Git SSH zu vermeiden
  4. No TLS Verify: Aktiviere für den Synology DSM-Eintrag „No TLS Verify”, da DSM ein selbstsigniertes Zertifikat verwendet

4. Nahtloser Git-SSH-Zugang

Die wahre „Magie” entsteht, wenn du deinen lokalen Rechner so konfigurierst, dass Git-SSH-Verbindungen automatisch über Cloudflare geleitet werden. So entfällt die Notwendigkeit, jedes Mal manuell Tunnel zu starten, wenn du pushen oder pullen möchtest.

Füge dies zu deiner SSH-Konfigurationsdatei hinzu (~/.ssh/config auf Mac/Linux, C:\Users\<benutzername>\.ssh\config auf Windows):

Host git.yourdomain.com
    HostName %h
    User git
    Port 2222
    ProxyCommand cloudflared access tcp --hostname %h

Was das bewirkt:

  • Leitet automatisch alle SSH-Verbindungen zu git.yourdomain.com über Cloudflare Access
  • Verwendet cloudflared als transparenten Proxy
  • Kein manuelles Tunnel-Setup erforderlich einfach git clone git@git.yourdomain.com:username/repo.git ausführen

Voraussetzungen:

  • Installiere cloudflared auf deinem lokalen Rechner: Cloudflare Download-Seite
  • Einmalige Authentifizierung: cloudflared access login

Fehlerbehebung: Falls Verbindungsprobleme auftreten, teste den Tunnel manuell:

cloudflared access tcp --hostname git.yourdomain.com --url localhost:2222

Dieser Befehl zeigt detaillierte Logs und hilft bei der Identifizierung von Authentifizierungs- oder Routing-Problemen.

5. Jellyfin-Performance & Hardware-Transkodierung

Da Jellyfin auf deiner Synology NAS läuft, ist die Optimierung der Performance entscheidend für eine flüssige Wiedergabe, insbesondere bei hochauflösenden Inhalten.

Direct Play vs. Transkodierung

  • Direct Play: Wenn dein Client das Medienformat nativ unterstützt, streamt Jellyfin die Datei unverändert mit minimalem CPU-Verbrauch. Dies ist für die meisten Szenarien ideal.
  • Transkodierung: Wenn eine Formatkonvertierung nötig ist (z. B. 4K zu 1080p oder inkompatible Codecs), kann die Transkodierung CPU-intensiv sein.

Hardware-Beschleunigung aktivieren

Um hardwarebeschleunigte Transkodierung auf der Synology zu aktivieren:

  1. Jellyfin-Dashboard öffnen: Navigiere zu jelly.yourdomain.com und melde dich als Admin an
  2. Transkodierungs-Einstellungen aufrufen: Dashboard → Wiedergabe → Transkodierung
  3. Hardware-Beschleunigung auswählen:
    • Intel NAS: Wähle „Intel QuickSync Video” (QSV)
    • AMD NAS: Wähle „Video Acceleration API (VA-API)”
    • NVIDIA GPU: Wähle „NVIDIA NVENC/NVDEC” (erfordert zusätzliche Einrichtung)

Intel QuickSync (am häufigsten bei Synology):

  • Unterstützt H.264, HEVC (H.265), VP9 und AV1 Codecs
  • Kann mehrere 4K-Streams gleichzeitig mit minimalem CPU-Verbrauch verarbeiten
  • Verfügbar auf den meisten Synology NAS mit Intel-Prozessoren (J-Serie, Plus-Modelle, etc.)

Hardware-Beschleunigung überprüfen

Nach der Aktivierung eine Mediendatei abspielen und prüfen:

  1. Dashboard → Aktive Geräte
  2. Nach „Transcode Reason” suchen sollte die Hardware-Methode anzeigen (z. B. „QSV”)
  3. CPU-Auslastung überwachen sollte während der Transkodierung niedrig bleiben

Profi-Tipp: Aktiviere „Prefer fMP4-HLS Media Container” in den Transkodierungs-Einstellungen für bessere Kompatibilität über verschiedene Geräte hinweg.

6. Sicherheit: Synology-Firewall-Konfiguration

Vergiss nicht die letzte Sicherheitsebene. Deine Synology-Firewall muss den Datenverkehr aus dem Docker-Netzwerk zu den Diensten durchlassen.

Firewall-Regeln

In DSM → Systemsteuerung → Sicherheit → Firewall:

  1. Neue Regel erstellen (wenn die Firewall aktiviert ist):

    • Ports: Erlaube 2222, 3000, 5001, 8096
    • Quell-IP: 172.24.0.0 mit Netzmaske 255.240.0.0 (dies deckt das Docker-Subnetz ab)
    • Protokoll: TCP
    • Aktion: Erlauben
  2. Warum das wichtig ist: Der Cloudflare-Tunnel-Container muss Gitea und Jellyfin erreichen können. Da sie alle im Docker-Bridge-Netzwerk (172.24.0.0/16) sind, stellt diese Regel sicher, dass die interne Docker-Kommunikation korrekt funktioniert.

Zusätzliche Sicherheitsempfehlungen

  • Cloudflare Access Policies aktivieren: Füge E-Mail- oder Identity-Provider-Authentifizierung zu deinen Tunneln hinzu als zusätzliche Sicherheitsebene
  • Regelmäßige Updates: Halte Docker-Images aktuell (docker-compose pull && docker-compose up -d)
  • Logs überwachen: Prüfe regelmäßig Container-Logs auf verdächtige Aktivitäten (docker logs <containername>)
  • DSM Auto-Blocker für Tunnel deaktivieren: Füge das Docker-Subnetz zur Erlaubnisliste hinzu, um zu verhindern, dass der Tunnel blockiert wird

Fortgeschritten: Domain-Sicherheitsregeln

Für eine zusätzliche Schutzebene kannst du Sicherheitsregeln in Cloudflare konfigurieren, um den Zugriff basierend auf IP-Adressen oder geografischen Standorten einzuschränken.

Navigiere zu deiner Domain im Cloudflare Dashboard → SecuritySecurity rulesCustom rulesEdit custom rule.

Beispiel: Zugriff nur auf dein Heimnetzwerk beschränken

(not ip.src in {2001:0db8:c0de:cafe::/64} and http.host wildcard "gitea.yourdomain.com") 
or (http.host wildcard "jelly.yourdomain.com" and not ip.src in {2001:0db8:c0de:cafe::/64}) 
or (http.host wildcard "internal.yourdomain.com" and not ip.src in {2001:0db8:c0de:cafe::/64})

Diese Regel blockiert den Zugriff auf deine Dienste, es sei denn, die Anfrage kommt aus deinem angegebenen IPv6-Subnetz. Ersetze 2001:0db8:c0de:cafe::/64 durch dein tatsächliches Heimnetzwerk-Präfix.

Beispiel: Bestimmte Länder blockieren

Du kannst auch ganze Länder blockieren (z. B. um automatisierte Angriffe zu reduzieren):

(ip.geoip.country in {"RU" "CN" "KP"}) and http.host wildcard "*.yourdomain.com"

Dies blockiert Datenverkehr aus Russland (RU), China (CN) und Nordkorea (KP). Passe die Ländercodes nach Bedarf an.

Profi-Tipp: Kombiniere beide Regeln mit and/or-Logik für granulare Kontrolle erlaube beispielsweise deine Heim-IP, während bestimmte Länder für allen anderen Verkehr blockiert werden.

Zusammenfassung

Du hast jetzt ein voll funktionsfähiges, sicheres Homelab-Setup mit:

  • Gitea: Privates Git-Hosting mit nahtlosem SSH-Zugang
  • Jellyfin: Leistungsstarkes Medienstreaming mit Hardware-Transkodierung
  • Cloudflare Tunnel: Sicherheit auf Unternehmensniveau ohne Portweiterleitung
  • Fernzugriff: Zugang zu allen Diensten von überall mit Zero-Trust-Sicherheit

All das läuft auf einer einzigen Synology NAS, geschützt durch Cloudflares globales Netzwerk, und ist weltweit zugänglich, ohne dein Heimnetzwerk preiszugeben.

Nächste Schritte

  • Automatische Backups einrichten für deine Gitea-Repositories und Jellyfin-Metadaten
  • Cloudflare Access Policies konfigurieren für zusätzliche Authentifizierungsebenen
  • Weitere Dienste hinzufügen zu deiner docker-compose.yml (z. B. Nextcloud, Bitwarden, Home Assistant)
  • Ressourcenverbrauch überwachen, um sicherzustellen, dass deine NAS die Last bewältigen kann