Zum Inhalt

Backup und Wiederherstellung

Sicherungen werden unter Administration > Betrieb > Sicherungen (/v2/admin/operations) eingerichtet: wann gesichert wird über die Sicherungs-Aktionen, wohin über das Speicherziel.

Der Ausführer läuft über restic (ADR 2026-08-11): calServer erzeugt den Datenbank-Dump und orchestriert Zeitplan und Aufbewahrung; restic trägt Ablage, Deduplizierung, Verschlüsselung und Integrität. Gesichert werden der Dump und die Anwendungsdateien (storage/app: DMS, Dateiverwaltung, Posteingang, Berichte).

Der Repo-Schlüssel ist die Sicherung

Jeder Lauf braucht BACKUP_RESTIC_PASSWORD in der Server-Umgebung (Host-.env bei Docker, Secret bei Kubernetes). Ohne Schlüssel läuft keine Sicherung — eine unverschlüsselte gibt es bewusst nicht. Der Schlüssel liegt absichtlich nicht in der Datenbank: dort wäre er im Ernstfall zusammen mit den Daten verloren.

Schlüssel setzen heißt Schlüssel im Passwort-Manager ablegen. Wer den Schlüssel verliert, verliert alle Sicherungen.

Grenzen des ersten Wurfs

Die Wiederherstellung ist kommandozeilengeführt (siehe unten), noch ohne Oberfläche. SFTP-Ziele brauchen einen SSH-Schlüssel — restic spricht SFTP über OpenSSH, eine Passwort-Anmeldung läuft unbeaufsichtigt nicht. MSSQL als V2-Engine hat noch keinen Dump-Weg (klare Fehlermeldung statt halber Sicherung); PostgreSQL und MySQL/MariaDB sind abgedeckt.


Sicherungs-Aktionen: wann gesichert wird

Feld Bedeutung
Beschreibung Bezeichnung der Sicherung
Beginn / Ende Zeitfenster, in dem die Sicherung laufen darf
Wochentage / Monate / Tage des Monats Wiederholung innerhalb des Fensters
Max. Sicherungen Wie viele Sicherungen aufbewahrt werden, bevor die älteste entfällt
Aktiv Deaktivierte Einträge laufen nicht

Kopieren legt eine Kopie der Konfiguration an, praktisch für eine zweite, abweichende Sicherung.

Speicherziel: wohin gesichert wird

Eine Sicherung im Container ist im Ernstfall keine

Vorgabe ist ein lokales Verzeichnis (storage/app/backups). Das funktioniert ohne Einrichtung, aber geht das Volume oder die Maschine verloren, sind die Sicherungen mit weg — also genau dann, wenn man sie braucht. Für den Regelbetrieb gehört das Ziel nach draußen.

Ablageart Wofür
Lokales Verzeichnis Einstieg, oder ein von außen eingehängtes Volume
S3-kompatibler Objektspeicher Amazon S3 und alles, was dessen Protokoll spricht: Objektspeicher beim Hoster, MinIO, Ceph, Garage im eigenen Haus
SFTP-Server Sicherungsziel im eigenen Netz, per Passwort oder privatem Schlüssel
Feld Bedeutung
Unterordner Trennt mehrere calServer-Installationen, die sich ein Ziel teilen. Optional.
Verzeichnis Nur bei lokaler Ablage. Leer bedeutet die Vorgabe.
Bucket / Region S3: Zielbehälter und Region. Dienste ohne Regionen vertragen die Vorgabe.
Endpunkt S3: nur für Dienste abseits von Amazon nötig, als vollständige URL
Pfad-Stil verwenden S3: nötig für die meisten selbst betriebenen Dienste ohne Bucket-Subdomains
Host / Port / Benutzer SFTP-Zugang
Geheimer Schlüssel, Passwort, Privater Schlüssel Zugangsdaten

Zugangsdaten

Geheimnisse werden verschlüsselt in der Datenbank abgelegt (Laravel Crypt, also gegen den APP_KEY der Installation) und nie im Klartext zurückgegeben. Das Formular zeigt nur, ob etwas hinterlegt ist; ein unverändert gelassenes Feld behält den gespeicherten Wert.

Nach einem Wechsel des APP_KEY

Ein mit einem anderen Schlüssel verschlüsselter Wert gilt als nicht hinterlegt, und das Formular verlangt eine Neueingabe. Das ist Absicht: Sonst scheiterte der Sicherungslauf an einer unlesbaren Zeichenkette, statt dass jemand den Zugang neu einträgt.

Verbindung testen

Verbindung testen schreibt eine kleine Probedatei, liest sie zurück und löscht sie wieder. Das Zurücklesen gehört dazu: Ein Ziel, auf das man schreiben, aber nicht lesen darf, nimmt Sicherungen an und gibt sie nicht wieder her — das fiele sonst erst bei der Wiederherstellung auf, also im schlechtestmöglichen Moment.

Ein fehlgeschlagener Test ist eine Auskunft, kein Fehler der Anwendung: Die Meldung des Ziels steht darunter.

Kein Fremddienst ohne Entscheidung

S3 und SFTP muss jemand aktiv eintragen. Ohne diese Angaben verlässt keine Datei den Server.

Läufe anstoßen und prüfen

Der Zeitplan läuft im Laravel-Scheduler (Aufgabe „Sicherungen", alle fünf Minuten geprüft, je Aktion höchstens ein Lauf pro Fenster). Von Hand:

# Fällige Aktionen ausführen (das tut auch der Scheduler):
docker exec calserver-api-v2 php artisan backup:run

# Eine bestimmte Aktion sofort, an der Fälligkeit vorbei:
docker exec calserver-api-v2 php artisan backup:run --action=1

Der Testlauf-Knopf an einer Aktion stößt denselben Lauf als Hintergrundaufgabe an; fehlt eine Voraussetzung (Schlüssel, Speicherziel), nennt die Antwort sie direkt. Die vorhandenen Sicherungen listet GET /api/v2/admin/backup-snapshots — live aus dem Repository, nicht aus einer eigenen Tabelle.

Wiederherstellung

Für die Wiederherstellung gibt es in calServer V2 noch keine Oberfläche. Der Weg führt über restic und die Werkzeuge der jeweiligen Datenbank:

# Snapshots ansehen (Repository-Adresse und Schlüssel wie im Container):
docker exec calserver-api-v2 sh -c 'restic snapshots'   # RESTIC_* siehe unten

# Einen Snapshot in ein Verzeichnis zurückholen:
docker exec calserver-api-v2 restic restore <snapshot-id> --target /tmp/restore

RESTIC_REPOSITORY und RESTIC_PASSWORD entsprechen dem Speicherziel und BACKUP_RESTIC_PASSWORD; bei S3 kommen die Zugangsdaten des Ziels dazu. Im zurückgeholten Verzeichnis liegt der Datenbank-Dump (database.pgdump bzw. database.sql) neben den Dateiverzeichnissen; ihn spielt das Werkzeug der jeweiligen Datenbank ein (pg_restore, mysql).

Nach einem Einspielen mit expliziten IDs unter PostgreSQL die Sequenzen nachziehen, sonst kollidiert der nächste Datensatz mit einer vergebenen Id:

docker exec calserver-api-v2 php artisan db:repair-sequences --dry-run
docker exec calserver-api-v2 php artisan db:repair-sequences