// Tutorial · Self-Hosting · Backup

Duplicati selbst hosten: Verschlüsselte Backups mit Web-UI

📅 05.09.2026 ⏱ 9 Min. Lesezeit ✍️ Redaktion

Backups machen ist nervig – bis der Moment kommt, in dem man sie braucht. Duplicati automatisiert das sichere Weglegen deiner Daten: verschlüsselt, inkrementell und komprimiert – auf lokale Laufwerke genauso wie in Cloud-Speicher. Die Bedienung läuft komplett über eine Web-Oberfläche. In diesem Tutorial richtest du Duplicati mit Docker Compose ein.

Warum Duplicati?

Duplicati ist ein ausgereifter Open-Source-Backup-Client mit Web-Oberfläche: Er erstellt verschlüsselte, inkrementelle und komprimierte Sicherungen – lokal auf ein Laufwerk oder remote über FTP, SSH/WebDAV sowie Cloud-Dienste wie S3, B2, OneDrive, Google Drive oder Mega. Die LinuxServer.io-Variante bringt das Ganze als pflegeleichten Docker-Container mit fester Verzeichnisstruktur.

Warum nicht einfach rsync/cp? Duplicati prüft Inhalte, dedupliziert sie und lagert sie verschlüsselt aus – inklusive Versionierung. Nach einem Ransomware-Fall oder Festplatten-Defekt hast du damit echte Wiederherstellungspunkte statt einer fehlerhaften Kopie.

Konzept: verschlüsselt & inkrementell

  • Verschlüsselung: Jede Sicherung wird mit einem eigenen Passwort/Schlüssel (AES) verschlüsselt – nur wer es kennt, kann die Backups lesen.
  • Inkrementell & dedupliziert: Nur geänderte Blöcke wandern ins Ziel – spart Speicher und Bandbreite bei jedem Lauf.
  • Ziele: Lokale Ordner (/backups), Netzwerkfreigaben (FTP/SSH/WebDAV) und gängige Clouds – vieles direkt aus der Oberfläche konfigurierbar.
  • Web-UI: Sicherungen planen, starten, prüfen und wiederherstellen – ganz ohne CLI-Wissen.
  • Versionen & Restore: Ältere Zustände bleiben erhalten; Wiederherstellungen laufen über denselben Assistenten.

Vorbereitung: Rechte & Ordner

mkdir -p ~/duplicati/appdata/config ~/duplicati/backups
cd ~/duplicati
  • ./appdata/config/config: Konfiguration und Datenbanken von Duplicati.
  • ./backups/backups: Ziel für lokale Sicherungen (z. B. file:///backups/…).
  • /:/source: macht den kompletten Host lesbar – nur nötig, wenn wirklich alles gesichert werden soll.
PUID/PGID=0 heißt Root: Deine Vorlage läuft mit PUID=0/PGID=0 – das ist die Konsequenz aus dem /-Mount: Nur Root kann das gesamte Dateisystem lesen. Damit hat der Container im Fehlerfall vollen Host-Zugriff. Wer gezielter sichert, mountet nur die nötigen Ordner und setzt PUID/PGID auf den Host-User (z. B. 1000:1000).

Docker Compose – die Datei

Deine Vorlage, bereinigt (leerer networks: {}-Block entfernt) und kommentiert:

services:
  duplicati:
    image: lscr.io/linuxserver/duplicati:latest
    container_name: duplicati
    restart: unless-stopped
    environment:
      - PUID=0                          # Root – nötig für den /-Mount
      - PGID=0
      - TZ=Europe/Berlin
      - CLI_ARGS=                       # optional: zusätzliche Argumente
      - DUPLICATI__WEBSERVICE_PASSWORD=MeinWEBSERVICEPASSWORD1234#  # Web-UI-Passwort
      - SETTINGS_ENCRYPTION_KEY=MeinENCRYPTIONKEY1234#              # verschlüsselt die Server-Einstellungen
    volumes:
      - ./appdata/config:/config        # Konfiguration & Datenbanken
      - ./backups:/backups              # Ziel für lokale Backups
      - /:/source                       # komplette Host-Festplatte als Quelle
    ports:
      # Host-Port : Container-Port
      - "127.0.0.1:50521:8200"          # Web-UI nur lokal, Proxy macht den Rest
  • lscr.io/linuxserver/duplicati:latest: Stable-Zweig; :development enthält Beta-Versionen.
  • 127.0.0.1:50521:8200: Duplicati-Web-UI auf Port 8200 im Container.
  • Das /-Mount sollte so eng wie möglich bleiben – lieber gezielte Pfade wie /etc, /home oder /opt/stacks einbinden.

Konfiguration: Passwörter & Schlüssel

VariableErklärung
DUPLICATI__WEBSERVICE_PASSWORDSetzt das Passwort der Web-Oberfläche direkt beim Start – kein interaktiver Ersteinrichtungs-Dialog nötig.
SETTINGS_ENCRYPTION_KEYVerschlüsselt die lokalen Server-Einstellungen/Datenbanken auf der Platte (AES) – schützt die Konfiguration, nicht die Backups selbst.
CLI_ARGSOptionale zusätzliche Startargumente für Duplicati (z. B. angepasste Pfade) – in der Regel leer.
PUID/PGIDNutzer/Gruppe, unter der der Prozess läuft – siehe Warnbox oben (hier bewusst 0 wegen des /-Mounts).
TZZeitzone des Containers – wichtig für korrekte Zeitstempel in Logs und Planung.
Schlüssel & Passwörter sichern: Die Werte stehen im Klartext in der Compose-Datei – lege sie in einer .env-Datei ab (chmod 600) und referenziere sie per ${VAR}. Ohne SETTINGS_ENCRYPTION_KEY kann Duplicati seine lokale Konfiguration nicht mehr entschlüsseln – beides gehört in den Passwortmanager. Die Backup-Passwörter der einzelnen Sicherungen sind davon unabhängig.

Reverse Proxy

Wie bei den anderen Tutorials binden wir die Oberfläche nur an localhost und stellen sie per TLS-Proxy bereit. Die Upgrade-Header schaden nicht und decken ab, falls die UI Verbindungen über WebSockets aufbaut:

server {
  listen 443 ssl;
  listen [::]:443 ssl;
  http2 on;
  server_name dc.meine.domain;

  access_log off;
  error_log /var/log/nginx/dc.meine.domain.error.log;

  # IP-Bereiche erlauben
  # TIPP: Nutze hier das /24 Subnetz, falls Docker die IP des Containers beim Update ändert
  # allow 10.42.42.0/24;
  # allow 10.42.42.41;
  # allow 127.0.0.1;
  # allow ::1;
  # allow 10.11.0.0/24;
  # allow 10.8.0.0/24;      
  # allow 10.0.0.0/24;
    
  # Alle anderen blockieren
  # deny all;
 
  # ---------------------------------------------------------------- Zertifikat (ECDSA)
  ssl_certificate     /etc/ssl/private/dc.meine.domain_ecc/fullchain.cer;
  ssl_certificate_key /etc/ssl/private/dc.meine.domain_ecc/dc.meine.domain.key;

  # ---------------------------------------------------------------- TLS-Feinschliff
  ssl_buffer_size 1400;                 # passt gut zu 1500-Byte-Ethernet-MTU
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_session_tickets off;              # Session-Tickets aus: bessere Forward Secrecy
  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers off;        # TLS 1.3 entscheidet der Client; aktueller Rat
  ssl_stapling on;
  ssl_stapling_verify on;
  ssl_ecdh_curve X25519:P-384:P-256:P-521;
  
  # OPTIMIERUNG 2: Lokalen Resolver (oder Quad9/Cloudflare) eintragen für besseren Datenschutz als Google
  resolver 9.9.9.9 1.1.1.1 valid=300s;
  resolver_timeout 5s;

  add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload" always;
  add_header X-Xss-Protection "1; mode=block" always;
  add_header X-Content-Type-Options nosniff always;
  
  # ERGÄNZUNG 1: Schützt deine Duplicati-Oberfläche davor, ungefragt in fremde iFrames eingebunden zu werden
  add_header X-Frame-Options "SAMEORIGIN" always;

   location / {
        # Standard-Proxy-Header
        proxy_read_timeout 300s;
        proxy_connect_timeout 300s;
        proxy_send_timeout 300s;
        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;

        # WICHTIG: WebSocket-Unterstützung für die Duplicati-UI
        proxy_set_header Upgrade $http_upgrade;
        
        # KORREKTUR 1: Dynamischer Verbindungs-Header für korrekte WebSocket-Handshakes
        proxy_set_header Connection "upgrade";

        # Verhindert fehlerhafte Weiterleitungen der Duplicati-UI
        proxy_redirect off;    
        
        proxy_pass http://127.0.0.1:50521;
        }
}
Web-UI schützen: In der Oberfläche liegen komplette Sicherungen samt Wiederherstellungs- Funktion. Ein starkes DUPLICATI__WEBSERVICE_PASSWORD ist Pflicht, wenn die UI nicht nur im lokalen Netz hängt.

Erster Start & erste Sicherung

cd ~/duplicati
docker compose up -d
docker compose logs -f duplicati

Danach https://dc.meine.domain öffnen:

  • Anmeldung mit dem Passwort aus DUPLICATI__WEBSERVICE_PASSWORD.
  • Unter „Add backup“ eine erste Sicherung anlegen: Quelle z. B. /config (die eigene Konfiguration!) oder /opt/stacks.
  • Als Ziel lokal /backups/mein-server wählen oder ein Cloud-Ziel über den Assistenten einrichten.
  • Ein eigenes Backup-Passwort vergeben (AES) – es schützt die Daten im Ziel.
  • Ersten Lauf starten und anschließend den Wiederherstellungs-Assistenten mit einer Testdatei durchspielen.
Regel 3-2-1 gilt auch hier: 3 Kopien deiner Daten, auf 2 verschiedenen Medien, davon 1 außer Haus. Duplicati erledigt die Automatisierung – für die „außer Haus“-Kopie sorgst du (oder dein Cloud-Ziel).

Backup des Backups: Restore-Tests

Ein Backup, das nie wiederhergestellt wurde, ist nur eine Hoffnung. Plane deshalb regelmäßige Restore-Tests ein: Lege eine Test-Sicherung an, stelle sie in einen leeren Ordner wieder her und prüfe die Dateien. Die Konfiguration selbst sicherst du am einfachsten mit, indem /config Teil einer Sicherung ist.

Betrieb in drei Sätzen: Updates per docker compose pull && docker compose up -d. SETTINGS_ENCRYPTION_KEY und Web-Passwort sicher aufbewahren (Passwortmanager). Nach jedem großen Update einmal die geplanten Sicherungen beobachten.

Häufige Probleme (FAQ)

ProblemLösung
Web-UI fragt trotz Env-Variable ein Passwort abContainer neu erstellen (docker compose up -d --force-recreate); Wert in der .env prüfen (Sonderzeichen wie # quoten).
Backup bricht mit „keine Berechtigung“ abBei /-Quelle Root nötig (PUID/PGID=0); bei gezielten Mounts gehört der Ordner dem gesetzten User.
„Settings cannot be decrypted“ / Konfiguration wegSETTINGS_ENCRYPTION_KEY stimmt nicht (mehr) – Schlüssel aus dem Passwortmanager wiederherstellen.
Ziel nicht erreichbar (S3/Cloud)Zugangsdaten und Region prüfen; erste Verbindung am besten über die Ziel-Assistenten testen.
Sehr große Sicherungen dauern langeInkrementelle Läufe sind nach dem ersten Voll-Backup deutlich schneller; ggf. Zeitfenster außerhalb der Stoßzeiten wählen.
Wiederherstellung liefert kaputte DateienBackup-Volumes prüfen (Verification), Ziel-Laufwerk testen und Restore an eine andere Stelle probieren.

Fazit

Duplicati nimmt dir die Ausrede: verschlüsselte, inkrementelle Sicherungen mit Web-UI – lokal oder in die Cloud – sind in einer halben Stunde eingerichtet. Der Preis dafür ist Verantwortung: Schlüssel und Passwörter sicher verwahren und Restore-Tests regelmäßig durchspielen. Dann hält das Backup, wenn es darauf ankommt.

Die vier Merksätze: ① Web-Passwort und Einstellungs-Schlüssel gehören in den Passwortmanager. ② Ohne SETTINGS_ENCRYPTION_KEY keine entschlüsselbare Konfiguration. ③ Jedes Backup braucht ein eigenes, sicheres Passwort. ④ Ein Backup ist erst ein Backup, wenn der Restore-Test bestanden wurde.
📝
....

Wir betreiben unsere komplette Infrastruktur selbst auf Open-Source-Software und schreiben nur über Tools, die wir im Alltag wirklich einsetzen. Fragen zum Artikel? Schreib uns.