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: