Zum Inhalt

App aus dem Backup wiederherstellen

Ungeprüft

Diese Anleitung ist noch nicht durchgespielt worden; Befehle, Bezeichnungen und erwartete Ausgaben können abweichen. Was noch zu prüfen ist, steht in todo/doku.md.

Ein Restore überschreibt den aktuellen Stand

Die Dateien der App werden auf den Stand des gewählten Snapshots zurückgesetzt; Dateien, die es damals noch nicht gab, werden gelöscht. Alles, was seitdem in der App geändert wurde, ist danach weg. Sprich einen Restore vorher in Signal ab.

Ziel

Eine App auf werner hat wieder die Daten aus einem nächtlichen Backup, und die anderen Apps bleiben unberührt.

Voraussetzungen

Alle Befehle laufen auf werner. Melde dich an mit:

Bash
ssh werner.garage-lab.de

Der Ablauf unten gilt für Apps mit Postgres-Datenbank, etwa HedgeDoc, Listmonk und Membertool. Für Discourse, Vaultwarden und Nextcloud gibt es Abweichungen; sie stehen bei den Schritten.

Schritte

1. Snapshot wählen

Bash
podman exec restic restic snapshots --host werner.garage-lab.de

Erwartet: eine Tabelle mit einem Snapshot je Nacht, die neuesten unten:

Text Only
1
2
3
4
ID        Time                 Host                  Tags                                         Paths
------------------------------------------------------------------------------------------------------------
3f9c2a1d  2026-09-30 03:21:07  werner.garage-lab.de  plan:nas-data,created-by:werner-garage-lab-de  /mnt/src/…
8b41e07c  2026-10-01 03:18:52  werner.garage-lab.de  plan:nas-data,created-by:werner-garage-lab-de  /mnt/src/…

Notiere die ID des Snapshots, dessen Stand du zurückhaben willst. Die Zeit ist UTC; der Snapshot enthält den Stand vom Beginn des Backup-Laufs in dieser Nacht.

Welche Dateien der App darin stecken, zeigt:

Bash
podman exec restic restic ls 8b41e07c /mnt/src/hedgedoc-server-uploads

2. App stoppen

Stopp alle Container der App außer der Datenbank, etwa bei HedgeDoc:

Bash
systemctl stop hedgedoc-server.service

Erwartet: keine Ausgabe; systemctl is-active hedgedoc-server.service zeigt inactive. Die Datenbank läuft weiter, weil sie in Schritt 4 den Dump einspielt.

Nextcloud: statt zu stoppen in den Wartungsmodus schalten:

Bash
podman exec -t -u www-data nextcloud-aio-nextcloud php occ maintenance:mode --on

Erwartet: Maintenance mode enabled.

Vaultwarden: systemctl stop vaultwarden-server.service.

Discourse: nichts stoppen; Discourse stellt sich in Schritt 4 selbst wieder her.

3. Dateien zurückholen

Bash
podman exec restic /bin/restic-restore 8b41e07c hedgedoc

Der zweite Wert ist der Name der App aus dem backup:-Block, also hedgedoc, listmonk, membertool, nextcloud, vaultwarden oder discourse.

Erwartet: restic listet die zurückgeholten Dateien und endet mit einer Zeile wie Summary: Restored 214 files/dirs (38.112 MiB) in 0:03. Meldet das Skript Unknown app, stimmt der Name der App nicht.

Bei einer App mit Datenbank liegt danach der Dump aus dem Snapshot als pg.dump im Backup-Volume der Datenbank.

4. Datenbank wiederherstellen

Apps mit Postgres (HedgeDoc, Listmonk, Membertool, Nextcloud): Der Container der Datenbank heißt <app>-postgres, bei der Nextcloud nextcloud-aio-database.

Bash
podman exec hedgedoc-postgres /bin/container-restore

Das Skript löscht die Datenbank, legt sie leer neu an und spielt pg.dump ein. Erwartet: viele Zeilen pg_restore: creating … und pg_restore: processing data for table …, am Ende keine Zeile mit error.

Vaultwarden: Zurückgeholt sind die Kopien db_<datum>_<zeit>.sqlite3; die aus dem Snapshot ersetzt die Datenbank:

Bash
1
2
3
podman exec restic ls /mnt/src/vaultwarden-server-data/
podman exec restic cp /mnt/src/vaultwarden-server-data/db_20261001_031812.sqlite3 /mnt/src/vaultwarden-server-data/db.sqlite3
podman exec restic rm -f /mnt/src/vaultwarden-server-data/db.sqlite3-wal /mnt/src/vaultwarden-server-data/db.sqlite3-shm

Erwartet: ls zeigt die Kopie aus dem Snapshot; cp und rm geben nichts aus. Dateianhänge kommen nicht zurück, weil sie nicht gesichert werden (siehe Vaultwarden).

Discourse: Zurückgeholt sind die Archive *.tar.gz im Volume discourse-server-backups. Spiel das gewünschte Archiv mit Discourse selbst ein:

Bash
1
2
3
podman exec -it discourse-server discourse enable_restore
podman exec -it discourse-server discourse restore <archiv>.tar.gz
podman exec -it discourse-server discourse disable_restore

Erwartet: discourse restore endet mit [SUCCESS].

Danach müssen die Beiträge neu aufbereitet werden. Das kann bei vielen Beiträgen lange dauern; starte es deshalb als eigene systemd-Unit, damit es weiterläuft, wenn die SSH-Verbindung abbricht:

Bash
systemd-run --unit=discourse-rebake --service-type=oneshot podman exec discourse-server rake posts:rebake_uncooked_posts
journalctl -fu discourse-rebake

Erwartet: Running as unit: discourse-rebake.service; im Journal am Ende Finished discourse-rebake.service. journalctl kannst du mit Strg+C beenden, ohne das Rebake abzubrechen. Die Namen der Archive zeigt podman exec restic ls /mnt/src/discourse-server-backups/default.

5. App wieder starten

Bash
systemctl start hedgedoc-server.service

Erwartet: keine Ausgabe; systemctl is-active hedgedoc-server.service zeigt active.

Nextcloud: Wartungsmodus aus und die Nextcloud informieren, dass sich ihre Daten geändert haben:

Bash
podman exec -t -u www-data nextcloud-aio-nextcloud php occ maintenance:data-fingerprint
podman exec -t -u www-data nextcloud-aio-nextcloud php occ maintenance:mode --off

Erwartet: Maintenance mode disabled.

Vaultwarden: systemctl start vaultwarden-server.service.

Prüfen

  • Die App ist unter ihrer Adresse erreichbar, und die Daten haben den Stand des Snapshots, etwa ein Dokument oder Beitrag, den es damals gab.
  • In den Logs der App stehen keine Fehler (Container-Status und Logs ansehen).
  • Auf deinem Rechner zeigt cue cmd plan in syslet/werner „No changes“; sonst läuft noch ein Container nicht, den du gestoppt hast.

Wenn etwas schiefgeht