mining
All checks were successful
Deploy / deploy-staging (push) Successful in 34s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-08-20 21:07:38 +02:00
parent c8f2f1c1ae
commit c345ee71cf
5 changed files with 292 additions and 7 deletions

View File

@@ -121,6 +121,7 @@ Aus [README.md](/home/lars/Schreibtisch/Projekte/desktop.kusche.berlin/docs/READ
- Keycloak bleibt das Auth-System
- das globale Desktop-Debug ist als Shell-Werkzeug unter `system/shell/desktop-debug/` definiert
- der Gitea-Deploy-Status liegt als optionales Addon unter `system/addons/gitea-deploy-status/`
- fuer die Staging-PostgreSQL-Instanz mit Portainer-Stack und Bind-Mount gibt es ein zentrales Recovery-Runbook unter `docs/POSTGRES_STAGING_RECOVERY.md`
### Module

View File

@@ -0,0 +1,171 @@
# PostgreSQL Staging Recovery
Runbook fuer den Fall, dass die Staging-PostgreSQL-Instanz per Portainer-Stack nicht mehr sauber startet und WAL- oder Checkpoint-Schaeden meldet.
Stand dieses Runbooks:
- Datum: `2026-08-20`
- Zielsystem: `staging.desktop.kusche.berlin`
- PostgreSQL-Image: `postgres:15-alpine`
- Datenpfad als Bind-Mount: `/mnt/db/postgres/nexus/staging:/var/lib/postgresql/data`
- Init-SQL als Bind-Mount: `/mnt/docker/containerdata/stackfiles/int/nexus/init-staging.sql:/docker-entrypoint-initdb.d/init.sql:ro`
## Typische Fehlersymptome
Beispielhafte Logmeldungen:
- `invalid resource manager ID in primary checkpoint record`
- `PANIC: could not locate a valid checkpoint record`
- `database system was interrupted`
Die Meldung `chmod: /var/run/postgresql: Operation not permitted` kann daneben auftreten, war in diesem Fall aber nicht die eigentliche Ursache des Startfehlers.
## Wichtige Grundregeln
- die bestehende Datenbasis nicht ungesichert loeschen
- in Portainer kein Volume-Reset oder `down -v` ausloesen
- vor jeder Reparatur ein Dateisystem-Backup des kompletten Bind-Mounts anlegen
- `pg_resetwal` nur als Rettungsmassnahme verwenden
- nach erfolgreichem Start immer sofort einen logischen Dump erzeugen
- eine mit `pg_resetwal` gerettete Datenbank nicht dauerhaft als Zielzustand weiterbetreiben
## Verwendete Sicherungen
Im dokumentierten Staging-Fall wurden diese Sicherungen erzeugt:
- Roh-Backup des Datenverzeichnisses: `~/pg-backups/postgres-staging-backup-2026-08-20.tar.gz`
- logischer Dump: `~/pg-backups/staging-rettung.dump`
## Sofortmassnahmen bei WAL- oder Checkpoint-Schaeden
### 1. Stack stoppen
In Portainer den betroffenen Staging-Stack vollstaendig stoppen, damit PostgreSQL nicht parallel auf das Datenverzeichnis schreibt.
### 2. Bind-Mount sichern
Auf dem Docker-Host:
```bash
mkdir -p ~/pg-backups
tar czf ~/pg-backups/postgres-staging-backup-2026-08-20.tar.gz -C /mnt/db/postgres/nexus staging
ls -lh ~/pg-backups/postgres-staging-backup-2026-08-20.tar.gz
```
### 3. Diagnosecontainer mit passender PostgreSQL-Major starten
```bash
docker run --rm -it \
-v /mnt/db/postgres/nexus/staging:/var/lib/postgresql/data \
postgres:15-alpine \
sh
```
Im Container:
```bash
pg_controldata /var/lib/postgresql/data
```
### 4. `pg_resetwal` erst als Dry-Run
`pg_resetwal` muss als PostgreSQL-Superuser ausgefuehrt werden. Deshalb Diagnosecontainer als User `postgres` starten:
```bash
docker run --rm -it \
--user postgres \
-v /mnt/db/postgres/nexus/staging:/var/lib/postgresql/data \
postgres:15-alpine \
sh
```
Im Container:
```bash
pg_resetwal -n /var/lib/postgresql/data
```
Wenn der Dry-Run plausibel aussieht, kann die eigentliche WAL-Ruecksetzung ausgefuehrt werden:
```bash
pg_resetwal -f /var/lib/postgresql/data
```
Danach den Container verlassen:
```bash
exit
```
### 5. Stack wieder starten
In Portainer den Staging-Stack wieder starten und pruefen, ob PostgreSQL ohne neue Fehler hochkommt.
### 6. Sofort einen logischen Dump erzeugen
Containernamen und Umgebungsvariablen pruefen:
```bash
docker ps
docker exec -it <postgres-container> env | grep POSTGRES
```
Im dokumentierten Fall waren die Werte:
- Datenbank: `nexus_staging`
- User: `rootNexusStaging`
In den laufenden Container wechseln:
```bash
docker exec -it <postgres-container> sh
```
Im Container:
```bash
pg_dump -Fc -U rootNexusStaging nexus_staging > /tmp/staging-rettung.dump
ls -lh /tmp/staging-rettung.dump
```
Zurueck auf dem Host den Dump herauskopieren:
```bash
docker cp <postgres-container>:/tmp/staging-rettung.dump ~/pg-backups/staging-rettung.dump
```
## Zielzustand nach erfolgreicher Rettung
Nach einem erfolgreichen `pg_resetwal` ist die Instanz nur wieder startbar gemacht. Der saubere Zielzustand ist:
1. frisches leeres PostgreSQL-Datenverzeichnis erzeugen
2. neue saubere Staging-Instanz initialisieren
3. `staging-rettung.dump` in die neue Instanz zurueckspielen
4. erst danach die alte reparierte Datenbasis ersetzen oder archivieren
## Restore in eine frische Staging-Instanz
Der empfohlene Ablauf ist:
1. aktuelle gerettete Datenbasis zusaetzlich archivieren
2. neues leeres Datenverzeichnis anlegen, z. B. `/mnt/db/postgres/nexus/staging-fresh`
3. Portainer-Stack oder Compose temporaer auf das neue Datenverzeichnis zeigen lassen
4. Stack starten, damit PostgreSQL sauber initialisiert
5. Dump `~/pg-backups/staging-rettung.dump` in die neue Instanz kopieren
6. mit `pg_restore` zurueckspielen
7. Anwendung gegen die frische Instanz testen
8. erst nach erfolgreichem Test das alte Datenverzeichnis abloesen oder umbenennen
Beispiel fuer den Restore in einen laufenden Container:
```bash
docker cp ~/pg-backups/staging-rettung.dump <postgres-container>:/tmp/staging-rettung.dump
docker exec -it <postgres-container> sh
pg_restore --clean --if-exists -U rootNexusStaging -d nexus_staging /tmp/staging-rettung.dump
```
Je nach Zielzustand kann statt `--clean --if-exists` auch ein Restore in eine frisch erzeugte leere Datenbank sinnvoller sein.
## Ablage im Projekt
Dieses Runbook dokumentiert den echten Staging-Vorfall vom `2026-08-20` und gilt als Referenz fuer weitere PostgreSQL-Wiederherstellungen auf diesem Projektstand.

View File

@@ -19,6 +19,9 @@ Zentraler Dokumentationsindex fuer das Projekt.
- [Umsetzungsanweisung/START_HIER.md](/home/lars/Schreibtisch/Projekte/desktop.kusche.berlin/docs/Umsetzungsanweisung/START_HIER.md)
Einstieg in die fachlichen Umsetzungsanweisungen und deren Reihenfolge.
- [POSTGRES_STAGING_RECOVERY.md](/home/lars/Schreibtisch/Projekte/desktop.kusche.berlin/docs/POSTGRES_STAGING_RECOVERY.md)
Runbook fuer WAL-/Checkpoint-Schaeden und Wiederherstellung der Staging-PostgreSQL-Instanz.
## Technische Projektstruktur
- `public/` Web-Root mit Desktop-Shell auf `/`
@@ -70,3 +73,4 @@ Aktuell wichtig:
- `Systemtools` und installierbare `Module` werden getrennt behandelt; Systemtools sind nicht Teil der Benutzer-Installationsauswahl
- das `Cron Tool` ist als globales Systemtool vorhanden und sammelt Modul-Cronjobs automatisch ueber Manifest-Metadaten
- Widgets und Cron-Endpunkte sollen von Modulen bevorzugt direkt in `module.json` beschrieben werden
- das PostgreSQL-Staging-Recovery-Runbook fuer Portainer-Stacks mit Bind-Mount liegt zentral unter `docs/POSTGRES_STAGING_RECOVERY.md`