Bitdoze-Logo

Zerobyte Restic GUI: Selbstgehostete Backup-Automatisierung (2026)

Zerobyte deployen – die Open-Source-Restic-GUI für selbstgehostete Backups. Setup mit Docker Compose & Dokploy, Recovery Keys, Mirror-Repos und Restore-Tipps (2026).

Dragos

Aktualisiert Veröffentlicht 29 Min. Lesezeit

Zerobyte Restic GUI: Selbstgehostete Backup-Automatisierung (2026)

Affiliate-Hinweis

Einige Links in dieser Anleitung sind Affiliate-Links. Wenn du darüber kaufst, erhalten wir möglicherweise eine kleine Provision – ohne zusätzliche Kosten für dich. Das hilft uns, diese Empfehlungen weiter zu testen und zu aktualisieren.

Wenn du einen VPS, ein Homelab oder irgendeinen Linux-Server betreibst, sind Backups die einzige Versicherung, die zählt. Platten sterben, Updates brechen Dinge und Fehler passieren. Zerobyte ist eine Restic-GUI, die ein sauberes Web-Dashboard über Restic legt – du bekommst selbstgehostete Backup-Automatisierung, ohne im Terminal zu leben.

Das Projekt hat sich schnell bewegt. Als diese Anleitung zuerst online ging, war das Image v0.19; die aktuelle stabile Linie ist v0.43.2 mit über 7.000 GitHub-Sternen, einer Doku-Site auf zerobyte.app und mehr als 20 stabilen Releases dazwischen. Der Kern-Workflow ist unverändert: Volumes, Repositories, geplante Jobs, Retention, Restores. Die operativen Details rund um Keys, Env-Vars und Exposition haben sich stark geändert. Dieses Update deckt das aktuelle Release von Ende zu Ende ab – einschließlich der Teile, die dich beißen, wenn du an einem alten Stack nur das Image-Tag hochziehst.

Was ist Zerobyte?

Zerobyte ist eine Open-Source-Plattform (AGPL-3.0) für Backup-Automatisierung, die die Restic-Engine mit einem modernen Dashboard ummantelt. Sie erledigt Repository-Erstellung, Scheduling, Retention und Restore-Workflows aus dem Browser – statt aus einem Haufen Cronjobs und Shell-Aliase.

Stell es dir als Restic-Web-UI mit angehängtem Scheduler vor. Die schwere Arbeit – Verschlüsselung, Deduplizierung, Repository-Format – bleibt bei Restic. Zerobyte ist die Kontrollebene darüber.

Warum Restic plus Zerobyte funktioniert

Schicht Verantwortung Was du bekommst
Restic Verschlüsselung, Deduplizierung, Kompression, Repo-Format Sichere und effiziente Backups
Zerobyte Web-UI, Scheduling, Retention, Mirrors, Logs Eine brauchbare Kontrollebene

Zusammen liefern sie dir schnelle, verschlüsselte Backups mit einem Workflow, den du Monate später noch verstehst. Sollte Zerobyte morgen verschwinden, bleiben deine Repositories normale Restic-Repos, die du mit der Standard-CLI und dem Recovery Key lesen kannst.

Die wichtigsten Funktionen

  • Automatisierte Backups mit Retention-Policies auf Restic-Basis
  • Ende-zu-Ende-Verschlüsselung standardmäßig, Keys über einen Recovery-Key-Flow gehandhabt
  • Flexible Zeitpläne plus On-Demand-„Backup now”-Läufe ohne Cron
  • Automatische Wiederholungen mit konfigurierbarer Anzahl und Verzögerung; unterbrochene Jobs werden nach einem Neustart wieder eingereiht
  • Multi-Backend-Repositories: lokal, S3-kompatibel, GCS, Azure, rclone-Remotes
  • Quell-Volumes aus lokalen Verzeichnissen, NFS, SMB, WebDAV und SFTP
  • Mirror-Repositories für 3-2-1-Setups, mit Backfill und Sync-Fortschritt in der UI
  • Kompressionsmodi off / auto / max, mit Override pro Job und eigenen Restic-Flags
  • Snapshot-Downloads im Browser, abbrechbare Restores, Restore an einen benutzerdefinierten Ort
  • Multi-User-Organisationen, 2FA, Passkeys, OIDC-SSO, API-Keys mit Ablaufdatum
  • Job-Logs, eine Activity-Seite für Hintergrundoperationen und Gesundheitsstatus der Benachrichtigungen

Noch 0.x, sehr aktiv entwickelt

Zerobyte ist noch in der 0.x-Serie. 2026 kamen viele Releases, mehrere waren Breaking: neue Pflicht-Env-Vars, eine Webhook-Allowlist, entfernte Secret-Referenz-Syntax. Pinne dein Image-Tag, lies die Release Notes vor dem Upgrade und rechne damit, dass sich die UI zwischen Minor-Versionen verschiebt.

Was sich seit unserer ersten Anleitung geändert hat

Wenn du nach der 2025er-Version dieses Artikels deployt hast: Das musst du wissen, bevor du irgendetwas anfasst.

Nur das Image-Tag zu erhöhen startet nicht

Wenn du nach unserer 2025er-Anleitung deployt hast: Das Image allein von v0.19 auf v0.43 zu ziehen startet den Container NICHT. APP_SECRET ist seit v0.23.0 Pflicht und BASE_URL seit v0.24.0. Ergänze beides, dann upgrade. Siehe Recovery Key und APP_SECRET und Zerobyte sicher aktualisieren.

Kurzfassung des Deltas:

  • Das Image ist jetzt ghcr.io/nicotsx/zerobyte:v0.43 (stable v0.43.2, Stand 2026-10-03). Der alte v0.19-Pin hinkt etwa 24 stabile Releases hinterher.
  • Zwei Pflicht-Umgebungsvariablen. APP_SECRET (seit v0.23.0) verschlüsselt Secrets in der Datenbank. BASE_URL (seit v0.24.0) muss die echte URL sein, mit der du die UI öffnest; ein https://-Präfix aktiviert Secure Cookies.
  • Recovery-Key-Modell für Repository-Passwörter. Repos, die in der UI angelegt werden, initialisiert Zerobyte mit einem organisationsweiten Restic-Passwort, das du einmal als restic.pass herunterlädst. Du erfindest dieses Passwort nicht mehr selbst.
  • Mirror-Repositories. Zerobyte synchronisiert jetzt nativ ein zweites Repository für 3-2-1-Setups. Für den Basisfall brauchst du kein externes Replikationstool.
  • WEBHOOK_ALLOWED_ORIGINS-Allowlist (v0.36.0). Selbstgehostetes ntfy, Gotify, generische Webhooks und eigene Shoutrrr-URLs brauchen eine explizite Origin-Allowlist. Slack, Discord, Pushover, Telegram und das öffentliche ntfy.sh nicht.
  • Der Auth-Stack ist erwachsen geworden. 2FA (v0.22), OIDC-SSO mit Organisationen (v0.30), Passkeys (v0.38), API-Keys mit Ablaufdatum (v0.40) und die Option, den Passwort-Login für reine SSO-Deployments zu deaktivieren (v0.40).
  • Das Image wurde kleiner und die App schneller. Von 597 MB auf 245 MB seit v0.27.0 – das Release, mit dem die App auf TanStack Start umzog.
  • Remote Agents existieren, aber nur in Alpha. zerobyte-agent-Binaries erschienen in v0.44.0-alpha.x (2026-10). Alpha, offiziell nicht supported, nicht für Produktion. Gilt genauso für die Desktop-Apps.

Ein Hinweis zu den Screenshots unten: Sie stammen aus der Dezember-2025-UI. Das v0.43-Interface hat eine neue Sidebar und eine Activity-Seite bekommen. Die Workflows sind gleich; das Drumherum nicht.

Voraussetzungen

  • Linux-VPS oder Homelab-Box mit installiertem Docker und Docker Compose
  • Rootful Docker. Rootless Docker kann die Kernel-Mounts nicht ausführen, die Zerobyte für NFS-/SMB-/WebDAV-Volumes nutzt
  • 2 GB RAM sind komfortabel; der offizielle Performance-Tuning-Guide zeigt, dass es mit GOMAXPROCS-Tweaks auch auf schwachen Boxen läuft
  • Lokale Platte für /var/lib/zerobyte (SQLite-Datenbank + Keys). Keine Netzwerk-Shares hier
  • Optional: rclone auf dem Host, wenn du rclone-backed Repositories willst (das rclone-Binary liegt im Image; die Host-Installation dient nur zum Erstellen der Config)
  • Eine Domain und ein Reverse Proxy, wenn du HTTPS willst – und das willst du
  • Auf TrueNAS: /var/lib ist flüchtig. Zeige /var/lib/zerobyte auf ein dediziertes Dataset, sonst frisst ein Upgrade deine Datenbank

Prüfe vor allem anderen, ob Docker sauber läuft:

bash
docker info >/dev/null && echo "rootful docker OK"

Wenn das ohne sudo fehlschlägt, läuft dein Daemon nicht oder dein User ist nicht in der docker-Gruppe. Das zuerst fixen.

Hetzner Cloud jetzt ausprobieren Hostinger VPS ausprobieren

Die VPS-Preise sind 2026 überall gestiegen. Wenn du eine gemietete Box überdenkst, schau dir an, was sich geändert hat und wann ein Mini-PC gewinnt. Wenn ein Mini-PC für dein Homelab gewinnt, ist der ASUS DC510 Mini-PC die Box-Klasse, die ich als leises lokales Backup-Ziel nehmen würde.

Kostenbild: Zerobyte selbst ist kostenlos (AGPL-3.0). Du zahlst für die Box (VPS-Klasse etwa 5 bis 10 Dollar im Monat oder einmal ein Mini-PC) und für das Storage-Backend, auf das deine Repositories zeigen. Der Repository-Abschnitt erklärt, wie du die Storage-Rechnung planbar hältst.

Zerobyte mit Dokploy installieren

Dokploy ist mein Standard für Docker-Apps, die eine Domain und TLS brauchen, ohne Traefik-Labels von Hand zu schreiben. Falls du es noch nicht hast, folge zuerst wie man Dokploy installiert.

Schritt 1: Den Service anlegen

  1. Öffne dein Dokploy-Projekt
  2. Klicke auf Add Service und wähle Compose
  3. Nenne es zerobyte

Wenn Compose-Services neu für dich sind, schau dir wie man eine Docker-Compose-App in Dokploy deployt für den kompletten Durchlauf dieses Screens an.

Schritt 2: Die Compose-Datei einfügen

Generiere zuerst das App-Secret und bewahre die Ausgabe außerhalb dieses Servers sicher auf:

bash
openssl rand -hex 32

Dann füge das in den Service ein:

yaml
services:
  zerobyte:
    image: ghcr.io/nicotsx/zerobyte:v0.43
    networks:
      - dokploy-network
    restart: unless-stopped
    cap_add:
      - SYS_ADMIN
    devices:
      - /dev/fuse:/dev/fuse
    environment:
      - TZ=UTC
      # required since v0.24; must match the URL you open in the browser. https:// enables Secure cookies
      - BASE_URL=https://zerobyte.example.com
      # required since v0.23; encrypts secrets stored in the DB. Use the openssl output from above
      - APP_SECRET=<openssl rand -hex 32>
      # v0.32.1+; makes rate limiting key off X-Forwarded-For behind your proxy
      - TRUST_PROXY=true
    volumes:
      - /etc/localtime:/etc/localtime:ro
      # keep this bind mount on local disk so you can back it up as a plain directory
      - /var/lib/zerobyte:/var/lib/zerobyte
      # sample local repository path, change to your storage
      - /srv/backups:/backups
      # sample source data to back up, read-only
      - /srv/data:/data:ro
      # optional, delete if you do not use rclone remotes
      - /etc/rclone:/root/.config/rclone:ro

networks:
  dokploy-network:
    external: true

Ein paar Anmerkungen zu dieser Compose-Datei:

  • Es gibt absichtlich keinen ports:-Block. Der Container bleibt im dokploy-network und Traefik erreicht ihn. Veröffentliche 4096 im Dokploy-Weg nicht auf dem Host.
  • /srv/backups ist ein Beispielpfad für ein lokales Repository. Passe ihn an deinen Speicherort an.
  • /srv/data sind die Quelldaten fürs Backup. Mounte Quellen möglichst read-only.
  • /etc/rclone ist optional. Entferne es, wenn du keine rclone-Remotes nutzt.
  • Die UI lauscht im Container auf Port 4096.

Schritt 3: Domain und Port

Lege in Dokploy eine Domain an und mappe sie auf Port 4096. Öffne nach dem Deploy https://zerobyte.example.com (was immer du in BASE_URL gesetzt hast), um die UI zu erreichen.

BASE_URL und Cookies

Secure Cookies werden nur aktiv, wenn BASE_URL mit https:// beginnt. Wenn du die UI über mehrere Hostnames auslieferst, liste die zusätzlichen in TRUSTED_ORIGINS. Passt die URL im Browser nicht zu BASE_URL, erwarte Login- und Callback-Probleme.

Storage-Warnung

Halte /var/lib/zerobyte auf lokaler Platte. Ein Netzwerk-Share verursacht oft Berechtigungsprobleme und schlechte Performance.

Verifizieren

bash
curl -sI https://zerobyte.example.com | head -5

Du willst HTTP/2 200 oder 302 plus TLS-Header sehen. Im Browser solltest du auf dem First-Run-Onboarding landen, und die App sollte dich zum Download des Recovery Keys drängen, bevor du irgendetwas anderes tun kannst. Dieses Verhalten ist korrekt. Lies den Recovery-Key-Abschnitt, bevor du wegklickst.

Fehlerbilder

  • Container in Restart-Loop: fehlendes APP_SECRET oder BASE_URL. Prüfe docker logs zerobyte.
  • 502 von Traefik: Domain nicht am Service oder auf einen anderen Port als 4096 gemappt.
  • Cookie-/Login-Loop hinter einem Proxy: BASE_URL passt nicht zur öffentlichen URL, oder der Proxy reicht X-Forwarded-Proto nicht durch.

Zerobyte mit Docker Compose installieren

Standalone-Weg, ohne PaaS. Nimm diesen, wenn du plain Docker auf einem VPS oder einem NAS betreibst. Das README beschreibt nach wie vor denselben Trade-off: eine Compose-Datei mit Privilegien für In-Container-Netzwerk-Mounts, eine ohne.

Beide Varianten unten pinnen ghcr.io/nicotsx/zerobyte:v0.43 und setzen BASE_URL + APP_SECRET. Generiere das Secret zuerst (openssl rand -hex 32).

Volles Setup (Remote-Mounts)

Nimm diese Variante, wenn Zerobyte NFS-, SMB-, WebDAV- oder SFTP-Shares im Container mounten soll. cap_add: SYS_ADMIN macht die eigentliche Arbeit; /dev/fuse wird für FUSE-basierte Mounts gebraucht (rclone mount, sshfs). Für CIFS ist es nicht nötig.

yaml
services:
  zerobyte:
    image: ghcr.io/nicotsx/zerobyte:v0.43
    container_name: zerobyte
    restart: unless-stopped
    cap_add:
      - SYS_ADMIN
    devices:
      - /dev/fuse:/dev/fuse
    ports:
      # loopback bind by default; see the note below
      - "127.0.0.1:4096:4096"
    environment:
      - TZ=UTC
      # required since v0.24. Change when you put a real domain on it
      - BASE_URL=http://127.0.0.1:4096
      # required since v0.23
      - APP_SECRET=<openssl rand -hex 32>
      # set true only behind a reverse proxy you control
      - TRUST_PROXY=false
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/lib/zerobyte:/var/lib/zerobyte
      - /srv/backups:/backups
      - /srv/data:/data:ro
      - /etc/rclone:/root/.config/rclone:ro

Einfaches Setup (lokale Ordner)

Wenn du nur lokale Verzeichnisse sicherst, lass die Capability und das FUSE-Device weg. Alle Repository-Typen funktionieren auch in dieser Variante. Das Einzige, was du verlierst, sind NFS-/SMB-/WebDAV-/SFTP-Mounts aus dem Container heraus.

yaml
services:
  zerobyte:
    image: ghcr.io/nicotsx/zerobyte:v0.43
    container_name: zerobyte
    restart: unless-stopped
    ports:
      - "127.0.0.1:4096:4096"
    environment:
      - TZ=UTC
      - BASE_URL=http://127.0.0.1:4096
      - APP_SECRET=<openssl rand -hex 32>
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/lib/zerobyte:/var/lib/zerobyte
      - /srv/data:/data:ro

Trade-offs

  • Kleinerer Blast Radius, weniger Privilegien
  • Völlig ok für lokale Verzeichnisse und jedes Repository-Backend
  • Keine In-Container-Mounts für NFS, SMB, WebDAV oder SFTP (auf dem Host mounten und den Pfad reinbinden)

Starten:

bash
docker compose up -d
docker logs -f zerobyte

Verifizieren

Die Logs zeigen einen sauberen Start, und curl -sI http://127.0.0.1:4096 liefert 200. Weil wir an Loopback gebunden haben, erreichst du die UI per SSH-Tunnel von deinem Arbeitsplatz:

bash
ssh -L 4096:localhost:4096 user@your-server
# then open http://127.0.0.1:4096

Das Binding 127.0.0.1:4096:4096 statt 4096:4096 ist Absicht. Veröffentlichte Container-Ports umgehen UFW-Regeln auf dem Docker-Host. Wenn du wirklich LAN-Zugriff auf 4096:4096 willst, lies zuerst warum veröffentlichte Docker-Ports deine Firewall-Regeln umgehen.

Fehlerbilder

  • Port 4096 schon belegt: ss -tlnp | grep 4096 und die Host-Seite ändern ("4097:4096").
  • Verwaiste Container nach einem Rename: docker compose ls zeigt den Projektnamen. Alte Experimente unter einem anderen Projektnamen können den Port oder den Bind-Pfad blockieren.
  • Restart-Loop: dasselbe fehlende Env-Var-Problem wie im Dokploy-Weg. docker logs zerobyte sagt welche.

Dein erstes Volume hinzufügen

Zerobyte sichert Daten aus Volumes – den Quellorten, die du in den Container mountest. Um ein lokales Verzeichnis zu sichern, binde es in der Compose-Datei ein und wähle es dann in der UI.

Beispiel-Host-Pfad:

diff
services:
  zerobyte:
    volumes:
      - /var/lib/zerobyte:/var/lib/zerobyte
+     - /srv/projects:/projects:ro

Gehe dann in Zerobyte auf Volumes und lege ein neues „Directory”-Volume an, das auf /projects zeigt.

Zerobyte-Volumes-Seite mit Backup-Quellen für lokale Verzeichnisse, NFS, SMB, WebDAV und SFTP

Unterstützte Volume-Typen sind jetzt lokale Verzeichnisse, NFS, SMB, WebDAV und SFTP (seit v0.21). Remote-Volume-Typen brauchen die volle Compose-Variante mit SYS_ADMIN. FUSE-artige Volumes bekommen standardmäßig Restics --ignore-inode-Verhalten (seit v0.36.0) – genau das, was du auf Netzwerk-Dateisystemen willst, wo Inode-Nummern lügen.

Volumes bekommen Health Checks und Auto-Remount. Fällt ein Share über Nacht aus, versucht Zerobyte es erneut, statt den Job einmal fehlschlagen zu lassen und still zu werden.

Verifizieren: Das Volume zeigt sich healthy in der UI und der Datei-Picker listet echte Dateien daraus. Ist der Picker leer, stimmt der Bind-Pfad im Container nicht.

Ein Repository anlegen

Repositories sind der Ort, an dem deine verschlüsselten Snapshots liegen. Hier hat sich das mentale Modell seit 2025 am stärksten geändert.

Du führst kein restic init mehr aus

Repositories, die in der UI angelegt werden, initialisiert Zerobyte mit einem organisationsweiten Restic-Passwort. Dieses Passwort lädst du einmal als Recovery Key (restic.pass) herunter. Eigene Repository-Passwörter gibt es nur für importierte oder externe Repos. Details im Recovery-Key-Abschnitt.

Repository-Typ Beispiele
Lokales Verzeichnis /var/lib/zerobyte/repositories/myrepo, oder ein gebundener Pfad wie /backups
S3-kompatibel AWS S3, MinIO, Wasabi, Backblaze B2, Cloudflare R2
Google Cloud Storage GCS-Buckets
Azure Blob Storage Azure-Container
rclone-Remotes Google Drive, Dropbox, OneDrive und Freunde

Zerobyte-Repositories-Seite mit lokalen, S3-, GCS-, Azure- und rclone-Storage-Backends

Wenn du ein Backend rein nach Kosten für ein Backup-Repository wählst, vergleiche vorher den günstigsten S3-kompatiblen Speicher für Backup-Repositories. Speicher ist billig; Egress beim Restore ist, wo die Rechnung auftaucht.

Repository-Optionen, die du kennen solltest:

  • Bandwidth Limits (v0.23), damit ein erstes Backup nicht den Uplink eines günstigen VPS sättigt
  • Kompressionsmodus off / auto / max, seit v0.42 pro Job überschreibbar
  • Editierbare Repositories (v0.28.1) statt löschen-und-neu-anlegen
  • Insecure TLS / Custom CA pro Repository (v0.21) für MinIO mit internen Zertifikaten
  • Auto-Health-Checks pro Repo deaktivierbar (v0.43), wenn ein Backend langsam und laut ist

Verifizieren: Das Repository zeigt sich als initialisiert und eine leere, aber valide Snapshot-Liste öffnet ohne Fehler. Ein nicht initialisiertes Repo lehnt das erste Backup mit einem Passwort- oder Backend-Fehler ab.

Kostenhinweis: Speicher plus Egress sind die wahren Kosten, nicht die Software. Bandwidth Limits verhindern, dass ein erster Sync eine getaktete Leitung frisst. Plane den Restore-Weg vor dem Backup-Weg.

rclone für Cloud-Speicher nutzen

  1. Installiere rclone auf dem Host: curl https://rclone.org/install.sh | sudo bash
  2. Konfiguriere ein Remote: rclone config
  3. Mounte die Config in den Container:
diff
services:
  zerobyte:
    volumes:
      - /var/lib/zerobyte:/var/lib/zerobyte
+     - ~/.config/rclone:/root/.config/rclone:ro

Wenn du den Container als Non-Root-User betreibst, setze RCLONE_CONFIG_DIR auf den Pfad, unter dem du sie gemountet hast. „No remotes available” in der UI bedeutet fast immer, dass die Config am falschen Pfad gelandet ist.

Nach einem Container-Neustart wählst du rclone als Repository-Typ und dein Remote aus.

Verifiziere es, bevor du ihm vertraust: Führe rclone listremotes, rclone ls remote: und einen Test-rclone mount auf dem Host aus. Wenn das Remote außerhalb von Zerobyte zickt, zickt es auch innerhalb. Auf dem Host zu debuggen ist immer schneller als durch die UI.

Recovery Key und APP_SECRET: deine echten Schlüssel

Dieser Abschnitt entscheidet, ob deine Backups in sechs Monaten noch wiederherstellbar sind. Zwei verschiedene Secrets, zwei verschiedene Aufgaben.

APP_SECRET verschlüsselt Credentials und Secrets in der Zerobyte-Datenbank (Repository-Passwörter, Notification-Tokens). Generiere es selbst (openssl rand -hex 32) und übergib es per APP_SECRET-Env-Var oder per APP_SECRET_FILE (v0.34.0), wenn du Docker Secrets nutzt. Seit v0.37.3 werden Werte, die unter einem anderen APP_SECRET verschlüsselt wurden, glatt abgelehnt – dieser Wert ist also tragend für Upgrades und Migrationen. Verlierst du ihn, werden gespeicherte Credentials unlesbar.

Der Recovery Key restic.pass ist das Restic-Repository-Passwort. Für in der UI angelegte Repos ist es der organisationsweite Standard. Das First-Run-Onboarding erzwingt einen Redirect auf /download-recovery-key, bis ein Owner oder Admin ihn mit Passwort-Wiedereingabe herunterlädt. Dieser nervige Flow ist genau der Sinn. Es ist die einzige Kopie des Passworts, das jedes von Zerobyte initialisierte Repo entsperrt.

APP_SECRETEnv-Var, die du erzeugstrestic.passRecovery Key aus der UIAPP_SECRET entschlüsselt DB-Credentialsrestic.pass entschlüsselt Restic-RepositoriesBewahre beide AUSSERHALB des Servers auf (Passwort-Manager + Offline-Kopie)Keys + Server verloren = Backups sind verschlüsseltes Rauschen

restic.pass + APP_SECRET verlieren = Datenverlust

Bewahre beide außerhalb des Servers auf, bevor du irgendetwas planst. Ein Passwort-Manager plus eine ausgedruckte oder Offline-Kopie reicht. Brennt der Server ab und beide Keys lagen nur dort, sind die Backups verschlüsseltes Rauschen. Die Doku ist hier aus gutem Grund deutlich.

Verschlüsselter Config-Export

v0.43.0 hat verschlüsselten Config-Export/-Import als passphrasengeschützte .zbex-Datei für Instance-Migrationen eingeführt, und die UI erinnert dich, den Recovery Key neu zu exportieren, wenn er älter als ein Jahr ist. Nutze ihn beim Umzug zwischen Boxen und behandle den Export mit derselben Sorgfalt wie den Key selbst.

Checkliste zur Key-Verwahrung:

  • restic.pass während des Onboardings herunterladen (nur Owner/Admin, Passwort-Wiedereingabe nötig)
  • restic.pass außerhalb des Servers aufbewahren: Passwort-Manager plus eine Offline-Kopie
  • APP_SECRET in dem Moment im selben Manager notieren, in dem du es generierst
  • Einen CLI-Unlock-Test fahren (Snippet unten), damit du weißt, dass der Key funktioniert
  • Den Recovery Key neu exportieren, wenn die UI warnt, dass er veraltet ist

Sperr dich wieder ein. Ist ein Admin ausgesperrt, setzt die mitgelieferte CLI die Credentials aus dem Container zurück:

bash
docker exec -it zerobyte bun run cli reset-password --username admin
# also available: disable-2fa, change-username, change-email, rekey-2fa, assign-organization
# passwords must be 8-128 characters

Verifizieren: Mit restic.pass unter /secure/restic.pass führe das CLI-Snippet im Restic-CLI-Abschnitt aus. restic snapshots sollte dasselbe listen wie die UI. Das beweist, dass der heruntergeladene Key der echte ist.

Fehlerbilder

  • Hängst auf dem Download-Screen fest: Absicht. Lade den Key herunter und der Redirect endet.
  • CLI sagt „wrong password”: Du nutzt ein selbst erfundenes Passwort statt restic.pass. Für UI-erstellte Repos gibt es nur ein korrektes Passwort, und das ist der Recovery Key.

Deinen ersten Backup-Job anlegen

Der Happy Path, sobald Volumes und Repositories existieren:

  1. Ein Quell-Volume und ein Repository wählen
  2. Einen Zeitplan setzen (täglich, wöchentlich oder eigener Cron)
  3. Include- und Exclude-Pfade hinzufügen
  4. Retention konfigurieren (daily, weekly, monthly, yearly behalten)
  5. Den Job einmal manuell laufen lassen, um Credentials und Performance zu verifizieren, bevor der Zeitplan feuert

Zerobyte-Backups-Ansicht mit geplanten Job-Läufen und Restic-Snapshots

Was die UI jetzt kann, was sie 2025 nicht konnte:

  • Backup now on demand, ohne einen Fake-Cron-Eintrag anzulegen (v0.33)
  • Automatische Wiederholungen mit konfigurierbarer Anzahl und Verzögerung (v0.34)
  • Unterbrochene geplante Backups werden nach einem Neustart wieder eingereiht statt still übersprungen (v0.41)
  • Eigene Restic-Flags pro Job: --read-concurrency, --exclude-larger-than, --no-scan, --pack-size
  • Kompressions-Override pro Job (v0.42), damit ein Repo sowohl kalte Archive als auch heiße Daten bedienen kann

Verifizieren: Job manuell laufen lassen, prüfen, dass ein Snapshot in der Liste auftaucht, und das Job-Log komplett lesen. Ein grünes Badge mit leerem Log ist ok. Ein grünes Badge mit Retries oben im Log solltest du verstehen, bevor du dem Zeitplan vertraust.

Ops-Hinweis: Lege den ersten Lauf in ein verkehrsarmes Zeitfenster. Das erste Backup ist I/O- und bandbreitenintensiv; inkrementelle sind es nicht.

Mirror-Repositories für 3-2-1-Backups

Ein Mirror ist ein zweites Restic-Repository, das Zerobyte mit deinem primären synchron hält. Das schließt die Lücke „aber meine Backups liegen auf demselben NAS wie die Daten”.

Quelldatendein ServerBackupBackupPrimäres Repolokal oder S3Offline-Kopieexterne Platte, rotiertMirror-SyncMirror-Repoanderer Anbieter3 Kopien, 2 Medien, 1 extern

Workflow in der UI:

  1. Lege ein zweites Repository bei einem anderen Anbieter oder Ort an (das ist das Mirror-Ziel).
  2. Hänge es als Mirror an das primäre an.
  3. Bestehende Snapshots per Backfill nachziehen. Die Backfill-UI gibt es seit v0.35.0; seit v0.43.0 kannst du pro Mirror fehlende Snapshots auswählen und genau diese syncen.
  4. Fortschritt beobachten und bei Bedarf abbrechen (Live-Fortschritt seit v0.42.0). Mirror-Sync-Fehler senden seit v0.43.2 Benachrichtigungen – genau das, was du willst.

Offizieller Artikel zum Muster: 3-2-1-Backup-Strategie.

Was Mirrors nicht reparieren

Mirrors schützen vor dem Verlust eines Repository-Backends. Sie schützen nicht vor einem kompromittierten Host, der beide Keys hält. Dafür sind die restic.pass-Aufbewahrung außerhalb des Servers und die Offline-Kopie da.

Und vergiss die Instance selbst nicht. Die Zerobyte-Datenbank ist klein, aber tragend. Sichere deine Dokploy-Metadaten auf Cloudflare R2, wenn Dokploy die App betreibt, und behandle /var/lib/zerobyte genauso. R2 (oder jedes günstige S3-Ziel) taugt auch als Mirror-Ziel.

Kostenhinweis: Ein Mirror verdoppelt grob die Storage-Kosten. Wähle ein bewusst langweiliges zweites Backend – keine zweite Kopie im selben Account und derselben Region.

Daten wiederherstellen

Öffne Backups, wähle einen Snapshot und stelle Dateien an ihren ursprünglichen Pfaden wieder her. Für Teil-Restores wählst du nur die Dateien, die du brauchst, und Zerobyte holt sie aus Restic.

Neu seit der ersten Anleitung:

  • Snapshot-Downloads im Browser (v0.29): Ein voller Snapshot streamt als .tar, eine einzelne Datei streamt roh. Praktisch, wenn du nur eine Config zurückbrauchst und keinen Restore-Job fahren willst.
  • Abbrechbare Restores (v0.41): Stoppe einen aus dem Ruder laufenden Restore, statt ihn auszusitzen.
  • Restore an einen benutzerdefinierten Ort, einschließlich eines Scratch-Verzeichnisses zur Verifizierung.
  • Restores von Read-Only-Volumes können nicht auf den Ursprungsort zielen (v0.42). Stelle stattdessen an einem beschreibbaren Ort wieder her.

Verifizieren: Stelle ein kleines Dateiset in ein Scratch-Verzeichnis wieder her und diff es gegen die Quelle, bevor du der Pipeline vertraust.

bash
diff -r /srv/data/sample /tmp/restore-test/sample && echo "restore verified"

Ein Backup, das du nicht restoren kannst, ist keins

Tu das einmal beim Deploy und dann alle paar Monate. Es ist der einzige Test, der zählt.

Benachrichtigungen

Stille Backup-Fehler sind der Standard-Fehlermodus jedes Backup-Tools. Leb nicht damit.

Zerobyte-Benachrichtigungseinstellungen für ntfy, Discord, Slack, Telegram und Webhooks

Ziele sind unter anderem Slack, Discord, Pushover, Telegram, Gotify, ntfy (Access-Token-Auth seit v0.21), generische Webhooks (v0.21) und eigene Shoutrrr-URLs. Seit v0.36.0 gibt es außerdem Pre-Backup- und Post-Backup-Webhooks, falls du eine App quiescen oder einen Job auf einer anderen Box anstoßen willst.

Jeder Benachrichtigungskanal zeigt Gesundheitsstatus und den letzten Zustellfehler (v0.36.0). Nutze das. Ein Kanal, der vor drei Tagen fehlschlug, ist genau der, der dir das fehlgeschlagene Backup von morgen nicht meldet.

WEBHOOK_ALLOWED_ORIGINS

Seit v0.36.0 brauchen ausgehende Webhooks, Gotify, selbstgehostetes ntfy und eigene Shoutrrr-URLs WEBHOOK_ALLOWED_ORIGINS – einen exakten Origin-Match aus Scheme + Host + Port (Pfade werden ignoriert). Wenn dein selbstgehostetes ntfy nach dem Upgrade über v0.36 hinaus still aufgehört hat zuzustellen, ist das der Grund. Das öffentliche ntfy.sh und die festen Anbieter (Slack, Discord, Pushover, Telegram) brauchen es nicht. Backup-Webhooks folgen keinen Redirects.

Verifizieren: Sende eine Test-Benachrichtigung und prüfe, dass der Gesundheitsstatus einen frischen Zustell-Zeitstempel zeigt. Für echte Abdeckung der Box selbst kombiniere das mit Server-Monitoring mit Beszel und Uptime Kuma, damit eine dunkel werdende Maschine auch ein Event ist und kein Rätsel.

Halt Zerobyte aus dem offenen Internet fern

Das README ist deutlich: Zerobyte internet-exponiert zu betreiben sei „highly discouraged”. Ich stimme zu. Diese App hält die Keys zu jedem Backup, das du besitzt.

Es gab einen Auth-Bypass

v0.19.0 (2025-12-17) fixte einen Authentifizierungs-Bypass, der jede vorherige Version betraf: API-Endpunkte waren ohne Session erreichbar. Pinne eine aktuelle Version und update zeitnah. Alte Tags einer Backup-Kontrollebene zu fahren ist der Weg, aus einem Plattenschaden einen Sicherheitsvorfall zu machen.

Expositionsleiter, beste zuerst:

  1. Nur privates Netzwerk. Leg Zerobyte auf Tailscale oder WireGuard und veröffentliche Port 4096 nie. Zerobyte liefert eine offizielle Tailscale-Anleitung; wenn du die Kontrollebene lieber selbst hostest, siehe einen Tailscale-Control-Server mit Headscale selbst hosten
  2. Reverse Proxy mit TLS plus Auth auf App-Ebene. Der Proxy muss X-Forwarded-Proto durchreichen; nutze TRUSTED_ORIGINS für zusätzliche Hostnames. v0.43.1 fixte den SSO-Login hinter HTTPS-zu-HTTP-Proxies – halte das Image aktuell, wenn du diese Form fährst. Anleitung: Reverse Proxy
  3. Wenn du überhaupt einen Port veröffentlichst, binde Loopback: 127.0.0.1:4096:4096, dann tunnel oder proxy rein. Niemals 0.0.0.0:4096. Denk daran, dass veröffentlichte Container-Ports UFW umgehen – siehe warum Docker deine Firewall umgeht (und der Fix)
  4. Härte die Box drumherum trotzdem: wie ich meinen Docker-Server abgesichert habe

Auth-Stack, den du einschalten solltest:

  • 2FA (v0.22) für jeden menschlichen Account
  • Passkeys (v0.38). Sie brauchen HTTPS oder localhost, wie jede andere WebAuthn-Implementierung
  • OIDC-SSO mit Organisationen und Einladungen (v0.30). Der Passwort-Login lässt sich für reine SSO-Deployments komplett deaktivieren (v0.40)
  • API-Keys mit Ablaufdatum (v0.40) statt langlebiger Tokens

Ehrliches Limit: Es gibt kein feingranulares RBAC. Organisationsmitglieder sind vertrauenswürdige Operatoren. Lade entsprechend ein.

Ops-Hinweis: Setze TRUST_PROXY=true nur hinter einem Proxy, den du kontrollierst. Es lässt das Rate-Limiting X-Forwarded-For vertrauen – nur sicher, wenn dir der Header-Pfad gehört.

Zerobyte sicher aktualisieren

Upgrades in der 0.x-Linie haben bisher alle mindestens einmal Handarbeit erfordert. Behandle sie wie Datenbank-Upgrades, nicht wie docker compose pull und hoffen.

  1. Pinne das Minor-Tag. ghcr.io/nicotsx/zerobyte:v0.43 ist ein wanderndes Minor-Tag und folgt dem neuesten v0.43.x-Patch. v0.43.2 ist der exakte Patch. Das Minor-Tag zu pinnen ist mein Standard; pinne den Patch, wenn du Byte-für-Byte-Reproduzierbarkeit brauchst.
  2. Lies zuerst die Release Notes. Das Breaking-Change-Register bisher: v0.23 (APP_SECRET Pflicht), v0.24 (BASE_URL Pflicht), v0.32 (env://- und file://-Secret-Referenzen entfernt, ersetzt durch PROVISIONING_PATH), v0.36 (WEBHOOK_ALLOWED_ORIGINS für selbstgehostete Notification-Endpunkte).
  3. Sichere /var/lib/zerobyte, bevor du bumpst. Es ist die SQLite-Datenbank plus Key-Material. Ein schlichtes tar des Verzeichnisses reicht:
bash
tar -C /var/lib -czf /srv/backups/zerobyte-$(date +%F).tar.gz zerobyte
  1. Bestätige, dass APP_SECRET und restic.pass außerhalb des Servers liegen. Du brauchst sie, wenn die Box mitten im Upgrade stirbt.
  2. Pull und Recreate:
bash
docker compose pull zerobyte
docker compose up -d
docker logs -f zerobyte

Wenn du Zerobyte als Dokploy-Compose-Stack betreibst, ist der Workflow Docker-Compose-Stacks in Dokploy aktualisieren. Und wenn du noch keine Offsite-Kopien der Instance-Daten hast, ist der Upgrade-Abschnitt ein guter Moment, damit anzufangen.

Rollback: Das alte Image-Tag zusammen mit dem Pre-Upgrade-Backup von /var/lib/zerobyte zurückspielen ist der Undo-Weg. Getestete Restores schlagen optimistische Upgrades; nimm den Tarball mit.

Verifizieren nach dem Upgrade: docker logs zerobyte ist sauber, die UI lädt, und ein Job läuft grün von Ende zu Ende.

Zerobyte Troubleshooting

NFS-/SMB-/WebDAV-Mount schlägt im Container fehl

Eskaliere in dieser Reihenfolge, geringste Privilegien zuerst:

  1. Beste Option: Den Share auf dem Host mounten (systemd-Unit oder autofs) und den Mountpoint als schlichtes Verzeichnis in den Container binden. Keine Extra-Caps nötig.
  2. cap_add: SYS_ADMIN. /dev/fuse nur für FUSE-basierte Mounts hinzufügen (rclone mount, sshfs). CIFS braucht es nicht.
  3. AppArmor-Hosts (Ubuntu/Debian): docker inspect --format '{{.AppArmorProfile}}' zerobyte ausführen. Kommt docker-default raus, füge security_opt: ["apparmor:unconfined"] hinzu.
  4. Seccomp-restriktive Umgebungen: security_opt: ["seccomp:unconfined"]. Letztes Mittel – es vergrößert die Angriffsfläche.
  5. SELinux-Hosts (CentOS/Fedora): security_opt: ["label:disable"].
rclone-Repositories: 'No remotes available'

Teste das Remote zuerst auf dem Host: rclone listremotes, rclone ls remote:, rclone mount. Schlägt es dort fehl, ist Zerobyte nicht das Problem.

„No remotes available” in der UI bedeutet, dass die Config-Datei am falschen Pfad gemountet ist. Das Image erwartet /root/.config/rclone. Läufst du als Non-Root, setze RCLONE_CONFIG_DIR auf den Pfad, den du gemountet hast.

Container restart-loopt beim Boot

Fast immer ein fehlendes APP_SECRET oder BASE_URL auf v0.23+. docker logs zerobyte nennt die Variable. Ergänzen, docker compose up -d erneut.

Repository ist gelockt

Seit v0.38.0 werden stale Locks automatisch entfernt und der Job versucht es erneut. In der UI gibt es seit v0.27.0 einen manuellen Unlock-Button. Nutze zuerst die UI; greif nur dann zu restic unlock per CLI, wenn die UI es nicht lösen kann.

Webhook- oder selbstgehostete ntfy-Benachrichtigungen kommen nicht mehr an

Prüfe zuerst WEBHOOK_ALLOWED_ORIGINS (siehe den Benachrichtigungs-Abschnitt). Dann lies den Kanal-Gesundheitsstatus für den letzten Zustellfehler. Backup-Webhooks folgen keinen Redirects – ein 302 von deinem Endpunkt ist ein stiller Fehlschlag.

Restic-CLI gegen Zerobyte-Repositories

Du kannst stock-restic weiter gegen alles nutzen, was Zerobyte verwaltet. Das mentale Modell hat sich aber geändert: Zerobyte initialisiert UI-erstellte Repos selbst, du erfindest also kein Passwort mehr und führst kein restic init aus.

Um ein Zerobyte-Repository per CLI zu lesen, nutze den heruntergeladenen Recovery Key:

bash
export RESTIC_REPOSITORY=/srv/backups/restic-repo
export RESTIC_PASSWORD_FILE=/secure/restic.pass   # downloaded from the Zerobyte UI
restic snapshots
restic check

Das Passwort ist keins, das du gewählt hast

Für UI-erstellte Repos ist das einzig korrekte RESTIC_PASSWORD das in restic.pass. Eigene Repository-Passwörter existieren nur für importierte oder externe Repos. Sagt die CLI „wrong password”, nutzt du die falsche Key-Quelle – kein Tippfehler.

Als Referenz: Das führt die Retention-Policy in der UI unter der Haube aus. Führe es nicht gegen Zerobyte-verwaltete Repos aus, es sei denn, du willst bewusst außerhalb der App prunen:

bash
restic -r $RESTIC_REPOSITORY forget --prune \
  --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --keep-yearly 3

Verifizieren: restic snapshots listet dieselben Snapshots, die die UI zeigt. Jede Abweichung heißt: falscher Repo-Pfad oder falscher Key.

FAQ

Brauche ich SYS_ADMIN und /dev/fuse?

Nur wenn Zerobyte NFS-, SMB-, WebDAV- oder SFTP-Shares im Container mounten soll. Für lokale Ordner nimm die vereinfachte Compose-Variante ohne Capability und Device. Jedes Repository-Backend funktioniert in beiden Varianten.

Wo speichert Zerobyte Repositories?

Lokale Repositories liegen standardmäßig unter /var/lib/zerobyte/repositories, es sei denn, du bindest einen anderen Pfad wie /backups und nutzt den. Cloud-Repositories liegen im konfigurierten Backend. Das Verzeichnis /var/lib/zerobyte hält außerdem die SQLite-Datenbank und Key-Material – deshalb bleibt es auf lokaler Platte und wird vor Upgrades gesichert.

Wo ist mein Restic-Passwort?

In der restic.pass-Datei, die du beim Onboarding heruntergeladen hast. Das ist der Recovery Key und zugleich das Repository-Passwort für jedes Repo, das Zerobyte initialisiert hat. APP_SECRET ist ein komplett anderes Secret: Es verschlüsselt Credentials in der Zerobyte-Datenbank. Beide gehören außerhalb des Servers. Siehe Recovery Key und APP_SECRET.

Kann Zerobyte andere Maschinen sichern?

Heute nicht als First-Class-Feature. Remote Agents (zerobyte-agent) erscheinen in der v0.44-Alpha-Linie (linux-x64/arm64-Binaries und ein Dockerfile.agent), mit Enrollment und einem systemd-Service im Repo. Alpha, offiziell nicht supported, nicht für Produktion. Die praktischen Workarounds aktuell: Shares von anderen Maschinen in die eine Instance mounten oder per SFTP-Volumes ziehen.

Wie viel RAM braucht es?

Es gibt kein offizielles Minimum. 2 GB sind komfortabel für UI plus Jobs. Der Performance-Tuning-Guide auf zerobyte.app dokumentiert die Regler GOMAXPROCS und RESTIC_PROGRESS_FPS für schwache Boxen – ein kleiner VPS oder ein Mini-PC ist also realistisch. Der schwere Ressourcenverbrauch ist Restics erster Backup-Lauf, nicht das Dashboard.

Ist Zerobyte kostenlos?

Ja. AGPL-3.0, kein Paid-Tier angekündigt, Stand Oktober 2026. Deine echten Kosten sind die Box, das Storage-Backend, Egress bei Restores und das Mirror-Ziel, wenn du 3-2-1 fährst. Bandwidth Limits pro Repository verhindern, dass erste Syncs einen getakteten Uplink fressen.

Fazit

Restic liefert dir vertrauenswürdige verschlüsselte Backups. Zerobyte gibt dieser Engine eine Kontrollebene, die du um 2 Uhr nachts noch verstehst: Zeitpläne, Retention, Mirrors, Logs und ein Restore-Weg, der nicht mit man restic anfängt. Die 2026er-Releases haben die meisten Lücken geschlossen, die ich in der ersten Version dieser Anleitung notiert hatte – vor allem native Mirror-Repositories und eine echte Doku-Site.

Wenn du einen Vergleich willst, der sich daneben lohnt: Pluton: selbstgehostete Backups mit Restic und Rclone umwickelt dieselbe Restic-Engine und gewinnt noch bei der Breite der rclone-Ziele (80+). Das alte Framing „Pluton hat Replikation und Zerobyte nicht” stimmt nicht mehr: Zerobyte deckt 3-2-1 heute mit Mirror-Repositories ab, und Remote Agents landen in Alpha. Wähle nach der UI, die du bevorzugst, und den Zielen, die du nutzt.

Operator-Checkliste, bevor du diesem Stack vertraust:

  • Recovery Key (restic.pass) heruntergeladen und außerhalb des Servers gelagert
  • APP_SECRET in deinem Passwort-Manager notiert
  • Ein manuelles Backup grün durchgelaufen
  • Ein kleiner Restore per diff gegen die Quelle validiert
  • Test-Benachrichtigung angekommen und der Kanal-Gesundheitsstatus ist frisch
  • Geplanter Job auf ein ruhiges Zeitfenster gelegt
  • Image auf v0.43 gepinnt
  • /var/lib/zerobyte irgendwo gesichert, das nicht diese Platte ist
Zerobyte auf GitHub ansehen
#Self-Hosted#Backup#Restic

Hat diese Anleitung bei dir funktioniert?

Brauchst du Hilfe bei Astro, VPS oder einer Self-hosted-App? Services ansehen →