OYSI DR-Cockpit passive only

Szenario: Daten-Korruption (wahrscheinlichstes Szenario)

Punktgenaue Wiederherstellung — eine einzelne DB, ein einzelnes Volume, ein einzelner Bind-Mount. Codex' Note: das Szenario passiert real, anders als VPS-Tot oder Pi-Tot.

1 Was vor X Stunden war? (Intraday-Slots)

Intraday-Backups laufen 4× täglich auf die Edge-Pis: 10/14/18/22 Uhr.

Zwischen 22:00 und 03:20 lebt der Stand nur auf den Pis (GAP P1-9 — kein S3 für die Slots).

  • Slot 10:00 — Vormittagsstand
  • Slot 14:00 — Mittagsstand
  • Slot 18:00 — Abendstand
  • Slot 22:00 — letzter Tagesstand vor Nightly
# Verfügbare Intraday-Slots auf Edge-1 listen:
ssh srvbackup@10.8.0.4 'ls -lt /backup/oysi-server/intraday/' | head -20
2 OVH Managed PG — PITR (Point-in-Time-Recovery)

11 CloudDBs auf ho113153-001. Console-URL UNKLAR (GAP P0-2).

  1. OVH Manager → Public Cloud → Databases → ho113153-001 → Tab "Backups".
  2. "Restore Point" auswählen (Window UNKLAR — PITR-Retention noch zu dokumentieren).
  3. OVH erstellt einen NEUEN DB-Cluster mit dem Restore-Point. Service-Connection-String muss umgeschwenkt werden.

STUB: Olivier muss die Console-URL in src/data/keys.json / links.astro nachtragen, sobald gemessen.

3 Einzelne CloudDB aus eigenem Dump zurückholen

Wenn die OVH-Plattform nicht greift oder ein einzelner Tabellenstand gebraucht wird.

# DATE = z.B. 20260429 (Vortagsstand). DBNAME = finance / shipping / dpp / ...
DATE=20260429
DBNAME=finance
ls /home/ubuntu/infrastructure/backups/clouddb/${DBNAME}_${DATE}_*.dump.age

age -d -i /home/ubuntu/infrastructure/keys/backup.key \
  -o /tmp/${DBNAME}.dump \
  /home/ubuntu/infrastructure/backups/clouddb/${DBNAME}_${DATE}_*.dump.age

# In neue temporäre DB einspielen, dann gezielt Tabellen kopieren:
PGPASSWORD=... pg_restore -h ho113153-001.eu.clouddb.ovh.net -p 35547 \
  -U ${DBNAME}_user -d ${DBNAME}_restore --no-owner --no-acl /tmp/${DBNAME}.dump
4 Einzelnes Docker-Volume restoren

22 Volumes werden täglich gesichert. Edge-1 hält 90d, S3 hält 365d.

# DATE = z.B. 20260429_030155
# VOLUME = z.B. zammad_zammad-data
DATE=20260429_030155
VOLUME=zammad_zammad-data

# Aus Edge-1 holen (schneller als S3):
rsync -av srvbackup@10.8.0.4:/backup/oysi-server/volumes/${DATE}/${VOLUME}.tar.gz.age /tmp/

age -d -i /home/ubuntu/infrastructure/keys/backup.key \
  -o /tmp/${VOLUME}.tar.gz /tmp/${VOLUME}.tar.gz.age

# Service stoppen, Volume neu erstellen:
docker compose -f /home/ubuntu/services/zammad/docker-compose.yml stop zammad-postgresql
docker volume rm ${VOLUME}
docker volume create ${VOLUME}
docker run --rm -v ${VOLUME}:/target -v /tmp:/backup alpine \
  sh -c 'cd /target && tar xzf /backup/${VOLUME}.tar.gz'

docker compose -f /home/ubuntu/services/zammad/docker-compose.yml up -d zammad-postgresql
5 Einzelner Bind-Mount restoren

Bind-Mounts (z.B. services/finance/uploads/) sind im selben Daily-Tar.

DATE=20260429_030155
BIND=finance_uploads

age -d -i /home/ubuntu/infrastructure/keys/backup.key \
  -o /tmp/${BIND}.tar.gz \
  /home/ubuntu/infrastructure/backups/volumes/${DATE}/bind_${BIND}.tar.gz.age

# In Service-Verzeichnis entpacken (Service vorher stoppen):
sudo tar xzf /tmp/${BIND}.tar.gz -C /home/ubuntu/services/finance/uploads/
6 ERPNext MariaDB — Tabellen-Restore
# Letzten Dump entschluesseln:
age -d -i /home/ubuntu/infrastructure/keys/backup.key \
  -o /tmp/erpnext.sql.gz \
  /home/ubuntu/infrastructure/backups/erpnext/_8dd95132afac5d61_$(date -d yesterday +%Y%m%d)_*.sql.gz.age

gunzip /tmp/erpnext.sql.gz

# In Side-DB einspielen:
docker exec -i erp-mariadb mariadb -uroot -p"$ROOT_PWD" \
  -e "CREATE DATABASE _8dd95132afac5d61_restore;"
docker exec -i erp-mariadb mariadb -uroot -p"$ROOT_PWD" _8dd95132afac5d61_restore < /tmp/erpnext.sql

# Dann gezielt Tabellen ueber INSERT ... SELECT zurueckkopieren.
7 Restore-Test triggern (vor Live-Schwenk)
sudo systemctl start backup-restore-test.service
sudo journalctl -fu backup-restore-test.service
# Prueft: clouddb-Decrypt + Restore in ephemeren PG :25432
# HTML-Mail an olivier.hoefer@oysi.gmbh nach Erfolg.