synops/docs/infra/backup.md
vegard 0f03886091 Backup: daglig PG-dump, STDB-krasj-recovery, helsesjekk (oppgave 12.2)
Tre ting implementert:

1. PG-dump rutine (scripts/backup-pg.sh):
   - Daglig cron kl. 03:00 UTC via /etc/cron.d/synops-backup
   - pg_dump -Fc (custom format, komprimert), konsistent uten nedetid
   - Rotasjon: beholder 30 dager, sletter eldre
   - Verifiserer at dump-filen er gyldig (ikke tom)

2. STDB → PG gjenoppbygging ved krasj (stdb_monitor.rs):
   - Bakgrunnsmonitor sjekker STDB hvert 30. sekund
   - Oppdager krasj (var oppe → nå nede)
   - Venter på at containeren restarter (maks 10 min)
   - Kjører warmup (PG → STDB) automatisk
   - Hele prosessen logges

3. Forbedret backup-helsesjekk (health.rs):
   - Sjekker /srv/synops/backup/pg/ for nyeste dump
   - Rapporterer ok/stale/missing i /admin/health
2026-03-18 11:11:32 +00:00

3.6 KiB

Backup og gjenoppbygging

Filsti: docs/infra/backup.md

Synops sin backup-strategi bygger på én innsikt: PostgreSQL er den eneste autoriteten. SpacetimeDB er en sanntidscache som gjenoppbygges fra PG ved behov. Media-filer i CAS er innholdsadresserte og immutable.

Arkitektur

PostgreSQL (autoritativ kilde)
  │
  ├──→ pg_dump daglig (03:00 UTC)
  │       └──→ /srv/synops/backup/pg/sidelinja_YYYYMMDD_HHMMSS.dump
  │              └──→ Rotasjon: 30 dager
  │
  └──→ SpacetimeDB (sanntidscache)
          └──→ Gjenoppbygges fra PG ved krasj (warmup)

1. PG-dump (daglig)

Script: scripts/backup-pg.sh Cron: /etc/cron.d/synops-backup0 3 * * * Logg: /srv/synops/logs/backup-pg.log Dumper: /srv/synops/backup/pg/

Prosess:

  1. Sjekker at PG-containeren kjører
  2. pg_dump -Fc (custom format, komprimert) — konsistent snapshot uten nedetid
  3. Verifiserer at dump-filen ikke er tom
  4. Sletter dumper eldre enn 30 dager

Manuell kjøring:

/home/vegard/synops/scripts/backup-pg.sh

Verifiser dump:

docker cp /srv/synops/backup/pg/DUMP.dump sidelinja-postgres-1:/tmp/test.dump
docker exec sidelinja-postgres-1 pg_restore --list /tmp/test.dump
docker exec sidelinja-postgres-1 rm /tmp/test.dump

2. STDB-gjenoppbygging ved krasj

Modul: maskinrommet/src/stdb_monitor.rs

SpacetimeDB er en sanntidscache. Hvis den krasjer, tapes ingen data fordi all skriving går gjennom maskinrommet som skriver til PG først (asynkront, men alltid). Gjenoppbygging skjer automatisk:

Ved oppstart

Maskinrommet kjører warmup::run() i main.rs — laster alle noder, edges og node_access fra PG til STDB.

Ved krasj under drift

stdb_monitor kjører i bakgrunnen og sjekker STDB hvert 30. sekund:

  1. Oppdager at STDB ikke svarer (var oppe, nå nede)
  2. Venter opptil 10 minutter på at containeren restarter
  3. Kjører warmup (PG → STDB) når STDB svarer igjen
  4. Logger hele hendelsesforløpet

Prosessen er automatisk og krever ingen manuell inngripen så lenge Docker restarter containeren (restart-policy: unless-stopped).

3. Restore fra backup

PostgreSQL

# Stopp maskinrommet (unngå skrivinger under restore)
sudo systemctl stop maskinrommet

# Restore fra dump
docker cp /srv/synops/backup/pg/sidelinja_YYYYMMDD.dump sidelinja-postgres-1:/tmp/restore.dump
docker exec sidelinja-postgres-1 pg_restore -U sidelinja -d sidelinja --clean /tmp/restore.dump
docker exec sidelinja-postgres-1 rm /tmp/restore.dump

# Start maskinrommet (warmup laster PG → STDB automatisk)
sudo systemctl start maskinrommet

Komplett gjenoppbygging

Ved total serversvikt (ny VPS):

  1. Installer OS og Docker (se docs/setup/produksjon.md)
  2. Start PG-container
  3. Restore dump (se over)
  4. Start maskinrommet (warmup håndterer STDB)
  5. Avledede data (segmenter, søkeindeks) regenereres fra kildene

4. Overvåking

Health-dashboardet (/admin/health) viser backup-status:

  • ok — dump-fil er fersk (< 25 timer gammel)
  • stale — dump-fil er eldre enn 25 timer
  • missing — ingen dump-filer funnet

Metrikk-endepunktet (/metrics) inkluderer STDB-status som del av helsesjekken.

5. Hva som IKKE backupes (bevisst)

  • SpacetimeDB — sanntidscache, gjenoppbygges fra PG
  • Redis — cache, regenereres automatisk
  • Caddy-data — sertifikater regenereres av Let's Encrypt
  • Whisper-modeller — re-download fra HuggingFace
  • Logger — rulleres med logrotate

Se docs/setup/produksjon.md § 11 for fullstendig backup-spesifikasjon inkludert off-site backup (rclone) og WAL-arkivering (fremtidig).