Beide mit Prüfsumme, beide in der Aufbewahrung, beide im Monatsstand, beide in der Selbstprüfung. Schlägt der Dokumententeil fehl, bricht der Lauf ab und räumt den angefangenen Datenbankstand weg.
Zwei Entscheidungen, die vom Issue abweichen
Kein mc mirror. Der MinIO-Client fehlt im Sicherungsbehälter und müsste bei jedem Lauf aus dem Netz geholt werden — eine Internetabhängigkeit im Sicherungspfad ist genau das, was man dort nicht will. Stattdessen wird das Verzeichnis direkt eingepackt. Das ist vertretbar, weil MinIO ein Objekt erst vollständig unter .minio.sys/tmp schreibt und dann umbenennt: Ein laufender Upload liegt nie halbfertig im Archiv, er fehlt höchstens. Derselbe Weg deckt den Dateitreiber mit ab.
Nur Lesezugriff. Der Dienst bekommt das Ablageverzeichnis mit :ro. Er läuft unbeaufsichtigt per cron; ein Fehler im Skript oder ein kompromittierter Behälter würde sonst Sicherung und Bestand auf einmal treffen. Deshalb schreibt die Wiederherstellung die Dateien auch nicht selbst an ihren Platz, sondern packt sie nach ./backups aus und gibt den letzten Handgriff als Einzeiler aus.
Geprüft
Die Kernlogik von Hand durchgespielt — packen, verschlüsseln, Selbstprüfung, zurückholen:
Inhalt kam bitgleich zurück (diff -r)
Klartext im Archiv nicht auffindbar
Selbstprüfung schlägt an bei beschädigtem Archiv und bei falschem Passwort
Dazu elf Prüfungen in tests/skripte.test.ts, gegen vier Mutationen getestet: Dokumententeil entfernt · Abbruch entfernt · Aufräumen halbiert · Schreibrecht erteilt — jede wird rot.
725 Unit-Tests, tsc und Lint sauber.
Nach dem Ausrollen
docker compose up -d erstellt den Sicherungsdienst neu — er braucht die neue Einhängung. Danach einmal von Hand prüfen:
Erwartet werden die Zeilen Datenbank gesichert, Dokumente gesichert und Selbstpruefung bestanden - Datenbank und Dokumente.
Closes #41
## Was jetzt passiert
Je Sicherungslauf entstehen zwei verschlüsselte Dateien mit demselben Zeitstempel:
```
cockpit_2026-09-01_0315.dump.enc <- Akte, Fristen, Buchungen
dokumente_2026-09-01_0315.tar.gz.enc <- Bescheide, Schreiben, Belege
```
Beide mit Prüfsumme, beide in der Aufbewahrung, beide im Monatsstand, beide in der Selbstprüfung. Schlägt der Dokumententeil fehl, bricht der Lauf ab und räumt den angefangenen Datenbankstand weg.
## Zwei Entscheidungen, die vom Issue abweichen
**Kein `mc mirror`.** Der MinIO-Client fehlt im Sicherungsbehälter und müsste bei jedem Lauf aus dem Netz geholt werden — eine Internetabhängigkeit im Sicherungspfad ist genau das, was man dort nicht will. Stattdessen wird das Verzeichnis direkt eingepackt. Das ist vertretbar, weil MinIO ein Objekt erst vollständig unter `.minio.sys/tmp` schreibt und dann umbenennt: Ein laufender Upload liegt nie halbfertig im Archiv, er fehlt höchstens. Derselbe Weg deckt den Dateitreiber mit ab.
**Nur Lesezugriff.** Der Dienst bekommt das Ablageverzeichnis mit `:ro`. Er läuft unbeaufsichtigt per cron; ein Fehler im Skript oder ein kompromittierter Behälter würde sonst Sicherung und Bestand auf einmal treffen. Deshalb schreibt die Wiederherstellung die Dateien auch nicht selbst an ihren Platz, sondern packt sie nach `./backups` aus und gibt den letzten Handgriff als Einzeiler aus.
## Geprüft
Die Kernlogik von Hand durchgespielt — packen, verschlüsseln, Selbstprüfung, zurückholen:
- Inhalt kam **bitgleich** zurück (`diff -r`)
- Klartext im Archiv nicht auffindbar
- Selbstprüfung schlägt an bei beschädigtem Archiv **und** bei falschem Passwort
Dazu elf Prüfungen in `tests/skripte.test.ts`, gegen vier Mutationen getestet: Dokumententeil entfernt · Abbruch entfernt · Aufräumen halbiert · Schreibrecht erteilt — jede wird rot.
**725 Unit-Tests**, `tsc` und Lint sauber.
## Nach dem Ausrollen
`docker compose up -d` erstellt den Sicherungsdienst neu — er braucht die neue Einhängung. Danach einmal von Hand prüfen:
```bash
docker compose exec sicherung /bin/sh /sicherung.sh
```
Erwartet werden die Zeilen `Datenbank gesichert`, `Dokumente gesichert` und `Selbstpruefung bestanden - Datenbank und Dokumente.`
Der Sicherungsdienst machte taeglich ein pg_dump und sonst nichts. Nach
einem Plattenschaden waere die Akte vollstaendig wiederhergestellt worden
- mit allen Eintraegen, Verweisen und Pruefsummen, aber ohne eine einzige
Datei dahinter. Die Pruefsumme in der Akte haette dann ein Dokument
belegt, das es nicht mehr gibt. Gegenueber dem Betreuungsgericht ist das
der schlechteste denkbare Zustand.
Je Lauf entstehen jetzt zwei verschluesselte Dateien mit demselben
Zeitstempel: der Datenbankstand und ein Archiv des Ablageverzeichnisses.
Beide mit Pruefsumme, beide in der Aufbewahrung, beide im Monatsstand,
beide in der Selbstpruefung.
Schlaegt der Dokumententeil fehl, bricht der Lauf ab und raeumt den
angefangenen Datenbankstand wieder weg. Eine Sicherung, die nur die halbe
Wahrheit enthaelt, aber vollstaendig aussieht, ist schlimmer als gar
keine: Man verlaesst sich darauf und merkt es erst im Ernstfall.
## Abweichung von der urspruenglichen Idee
Im Issue stand "mc mirror statt rohem Verzeichnis". Beim Umsetzen zeigte
sich, dass der MinIO-Client in diesem Behaelter fehlt und bei jedem Lauf
aus dem Netz geholt werden muesste. Eine Internetabhaengigkeit im
Sicherungspfad ist genau das, was man dort nicht will.
Stattdessen wird das Verzeichnis direkt eingepackt. Das ist vertretbar,
weil MinIO ein Objekt erst vollstaendig unter .minio.sys/tmp schreibt und
dann an seinen Platz umbenennt: Ein laufender Upload liegt nie halbfertig
im Archiv, er fehlt hoechstens. Derselbe Weg deckt den Dateitreiber mit
ab.
## Nur lesend
Der Sicherungsdienst bekommt das Ablageverzeichnis mit ":ro" eingehaengt.
Er laeuft unbeaufsichtigt per cron; ein Fehler im Skript oder ein
kompromittierter Behaelter wuerde sonst Sicherung und Bestand auf einmal
treffen - genau der Fall, gegen den eine Sicherung da ist.
Deshalb schreibt die Wiederherstellung die Dateien auch nicht selbst an
ihren Platz, sondern packt sie nach ./backups aus und gibt den letzten
Handgriff als Einzeiler aus. In ein laufendes MinIO hineinzuschreiben
wuerde dessen Datenbestand ohnehin beschaedigen.
## Geprueft
Die Kernlogik einmal von Hand durchgespielt: packen, verschluesseln,
Selbstpruefung, zurueckholen - der Inhalt kam bitgleich zurueck, der
Klartext war im Archiv nicht auffindbar, und die Selbstpruefung schlug
sowohl bei einem beschaedigten Archiv als auch bei falschem Passwort an.
Dazu elf Pruefungen in tests/skripte.test.ts gegen vier Mutationen:
Dokumententeil entfernt, Abbruch entfernt, Aufraeumen halbiert,
Schreibrecht erteilt - jede wird rot.
Refs #41
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #41
Was jetzt passiert
Je Sicherungslauf entstehen zwei verschlüsselte Dateien mit demselben Zeitstempel:
Beide mit Prüfsumme, beide in der Aufbewahrung, beide im Monatsstand, beide in der Selbstprüfung. Schlägt der Dokumententeil fehl, bricht der Lauf ab und räumt den angefangenen Datenbankstand weg.
Zwei Entscheidungen, die vom Issue abweichen
Kein
mc mirror. Der MinIO-Client fehlt im Sicherungsbehälter und müsste bei jedem Lauf aus dem Netz geholt werden — eine Internetabhängigkeit im Sicherungspfad ist genau das, was man dort nicht will. Stattdessen wird das Verzeichnis direkt eingepackt. Das ist vertretbar, weil MinIO ein Objekt erst vollständig unter.minio.sys/tmpschreibt und dann umbenennt: Ein laufender Upload liegt nie halbfertig im Archiv, er fehlt höchstens. Derselbe Weg deckt den Dateitreiber mit ab.Nur Lesezugriff. Der Dienst bekommt das Ablageverzeichnis mit
:ro. Er läuft unbeaufsichtigt per cron; ein Fehler im Skript oder ein kompromittierter Behälter würde sonst Sicherung und Bestand auf einmal treffen. Deshalb schreibt die Wiederherstellung die Dateien auch nicht selbst an ihren Platz, sondern packt sie nach./backupsaus und gibt den letzten Handgriff als Einzeiler aus.Geprüft
Die Kernlogik von Hand durchgespielt — packen, verschlüsseln, Selbstprüfung, zurückholen:
diff -r)Dazu elf Prüfungen in
tests/skripte.test.ts, gegen vier Mutationen getestet: Dokumententeil entfernt · Abbruch entfernt · Aufräumen halbiert · Schreibrecht erteilt — jede wird rot.725 Unit-Tests,
tscund Lint sauber.Nach dem Ausrollen
docker compose up -derstellt den Sicherungsdienst neu — er braucht die neue Einhängung. Danach einmal von Hand prüfen:Erwartet werden die Zeilen
Datenbank gesichert,Dokumente gesichertundSelbstpruefung bestanden - Datenbank und Dokumente.