Aqbeż għall-kontenut

Backup, irkupru puntwal u d-drill tar-restore

Agħmel backup ta' Quire, irrestawraha għal punt fiż-żmien, u ppruvaha bid-drill tar-restore.

Ara bħala Markdown

Id-disinn jinsab f’docs/architecture/23-ops.md sezzjoni 8. Dan huwa r-runbook għall-prodott Docker Compose. Jinkiteb biex jiġi segwit minn xi ħadd li ma kitbux; jekk pass mhuwiex ċar, dak huwa difett f’dan id-dokument.

X’inhu protett, u kif

Asset How Where
Id-database WAL arkivjat kontinwament, kull 60 sekonda l-aktar, mill-ewwel boot Volum pgwal
Id-database Backups bażi b’pg_basebackup, kuljum default (backup-scheduler) Volum pgbackup
Id-database Kopji encrypted tal-backups bażi u l-WAL, kull ħames minuti (backup-offsite) Maħżen separat li ssemmi int
Files Il-volum files. Ikkopjah bl-għodda tal-backup tal-host tiegħek, jew uża ħażna ta’ oġġetti verżjonata Volum files
Secrets docker/.env, fuq kollox QUIRE_MASTER_KEY (u kwalunkwe QUIRE_MASTER_KEY_RETIRED li għadu jintuża), QUIRE_BACKUP_ENCRYPTION_KEY, u docker/secrets/audit-signing-key.pem Żomm kopja barra dan il-host
Search indexes, caches, renditions Mhux backed up; mibnija mill-ġdid

Miri: punt ta’ rkupru fi żmien 60 sekonda mill-ħsara, u restore fi żmien 60 minuta għal database ta’ 500 GB.

Żewġ żbalji huma komuni. Database rrestawrata mingħajr il-fajls tagħha tagħmel paġni miksura. Database rrestawrata mingħajr QUIRE_MASTER_KEY ma tistax tiddekripta l-kredenzjali SSO, webhook u integrazzjoni li żżomm; sakemm rotazzjoni ta’ ċavetta master tintemm b’xejn mhux solvut (key-rotation.md), dan jinkludi ċ-ċwievet irtirati. It-tnejn huma parti mill-backup.

Teħid ta’ backups

Backup bażi tal-cluster kollu:

docker compose -f docker/compose.yaml --profile backup run --rm backup

Iżomm l-aktar backups bażi ġodda ta’ QUIRE_BACKUP_KEEP (default 5) u jneħħi WAL li l-eqdem waħda ma teħtieġx aktar, biex l-arkivju ma jistax jikber bla limitu. Skedaha kuljum b’cron jew timer systemd fuq il-host:

15 2 * * * cd /srv/quire && docker compose -f docker/compose.yaml --profile backup run --rm backup >> /var/log/quire-backup.log 2>&1

Jew ħalli l-istack tiskedaha: il-profil backup imexxi backup-scheduler, li jieħu backup bażi kull QUIRE_BACKUP_INTERVAL_HOURS (default 24), u backup-offsite, deskritt wara.

docker compose -f docker/compose.yaml --profile backup up -d

Kopji encrypted barra l-host

Iż-żewġ volumi jgħixu fuq l-istess host mad-database, u backup fuq il- magna li falliet mhuwiex backup. backup-offsite jikkopja kull backup bażi u kull segment WAL arkivjat lil maħżen separat permezz tal-port tal-ħażna, encrypted, u jżommhom hemmhekk taħt retention:

  • Encryption. AES-256-GCM b’QUIRE_BACKUP_ENCRYPTION_KEY (jew il-fajl imsemmi minn QUIRE_BACKUP_ENCRYPTION_KEY_FILE): 32 bytes, minn openssl rand -hex 32. Kull fajl għandu n-nonce tiegħu u tag tal-awtentikazzjoni, biex kopja ma tinqarax mingħajr iċ-ċavetta u kwalunkwe bidla fiha tiġi skoperta. Żomm iċ-ċavetta ma’ QUIRE_MASTER_KEY, ’il bogħod minn dan il-host u ’l bogħod mill-maħżen tal-backup. Mingħajr iċ-ċavetta m’hemm l-ebda restore.
  • Fejn. QUIRE_BACKUP_STORAGE_DRIVER huwa s3, azure jew local (disk remot mounted f’QUIRE_BACKUP_STORAGE_ROOT). Is-settings huma dawk tal-ħażna tal-fajls b’prefiss QUIRE_BACKUP_: QUIRE_BACKUP_S3_ENDPOINT, QUIRE_BACKUP_S3_BUCKET, QUIRE_BACKUP_S3_ACCESS_KEY_ID, eċċ. Uża bucket differenti u, idealment, kont differenti mill-fajls, b’ kredenzjali li jistgħu jiktbu iżda ma jħassrux jekk il-fornitur jippermetti.
  • Retention. L-aktar backups bażi ġodda ta’ QUIRE_BACKUP_OFFSITE_KEEP (default QUIRE_BACKUP_KEEP, inkella 7) u l-WAL li l-eqdem minnhom teħtieġ; settijiet u segmenti eqdem jitħassru mill-maħżen.
  • Meta. Kull QUIRE_BACKUP_SHIP_INTERVAL_SECONDS (default 300). Il-bagħt huwa idempotenti: dak li diġà huwa maħżen jinqabeż, u backup bażi jgħodd bħala maħżen biss ladarba l-manifest tiegħu jinkiteb, l-aħħar.

L-istess kmand jaħdem bl-idejn:

docker compose -f docker/compose.yaml run --rm backup-offsite bun apps/worker/src/backups/main.ts ship
docker compose -f docker/compose.yaml run --rm backup-offsite bun apps/worker/src/backups/main.ts verify

Biex tirrestawra fuq host ġdid, ġib sett lura l-ewwel, imbagħad segwi l-passi hawn taħt bid-directory miġjuba minflok il-volum pgbackup u l- wal-archive miġjub minflok pgwal:

bun apps/worker/src/backups/main.ts fetch base-20260924T021500Z /srv/restore

Restore għal punt fiż-żmien

Uża dan wara telf ta’ data: importazzjoni ħażina, kors imħassar, migrazzjoni contract li għandek bżonn tħassar. Tissostitwixxi d-database live, għalhekk ipprattikaha bid-drill hawn taħt l-ewwel.

  1. Agħżel il-ħin fil-mira, f’UTC, ftit qabel il-ħsara: 2026-09-24 09:30:00+00. Il-log tal-verifika (/admin/audit) normalment juri l- mument.
  2. Waqqaf kull ma jikteb: docker compose -f docker/compose.yaml stop web content worker scheduler collab
  3. Żomm il-cluster imħassar sakemm ir-restore jiġi vverifikat:
    docker compose -f docker/compose.yaml stop postgres
    docker run --rm -v quire_postgres18-data:/from -v quire_postgres-damaged:/to alpine cp -a /from/. /to/
  4. Iftaħ l-aktar backup bażi ġdid eqdem mill-mira fil-volum tad-data, u itlob irkupru mmirat:
    docker run --rm -v quire_pgbackup:/backups:ro -v quire_postgres18-data:/var/lib/postgresql postgres:18-alpine sh -euc '
      base="$(ls -1d /backups/base-* | sort | tail -n 1)"   # or the one before the target
      rm -rf /var/lib/postgresql/18/docker && mkdir -p /var/lib/postgresql/18/docker
      tar -xzf "$base/base.tar.gz" -C /var/lib/postgresql/18/docker
      touch /var/lib/postgresql/18/docker/recovery.signal
      chown -R postgres:postgres /var/lib/postgresql/18/docker && chmod 700 /var/lib/postgresql/18/docker'
  5. Irkupra: ibda Postgres darba bis-settings tal-irkupru, minn override ta’ Compose biex il-fajl normali ma jintmessx:
    # docker/compose.recover.yaml
    services:
      postgres:
        command: [postgres, -c, "restore_command=cp /var/lib/postgresql/wal-archive/%f %p",
                  -c, "recovery_target_time=2026-09-24 09:30:00+00",
                  -c, recovery_target_action=promote, -c, archive_mode=off,
                  -c, max_connections=200, -c, hba_file=/etc/postgresql/pg_hba.conf]
    L-override tissostitwixxi l-kmand kollu, għalhekk tirrepeti ż-żewġ settings li l-irkupru jiddependi fuqhom: max_connections mhux inqas mill-primarja (inkella l-irkupru jabbanduna b’“insufficient parameter settings”) u il-pg_hba.conf mounted.
    docker compose -f docker/compose.yaml -f docker/compose.recover.yaml up -d postgres
    docker compose -f docker/compose.yaml logs -f postgres   # wait for "database system is ready"
  6. Iċċekkjaha qabel ma tħalli lil ħadd jidħol: il-katina tal-verifika (docker compose -f docker/compose.yaml run --rm worker bun tooling/audit-verify/run.ts), u li d-data mitlufa reġgħet lura.
  7. Erġa’ għan-normal: docker compose -f docker/compose.yaml up -d. Dan jerġa’ jibda Postgres bl-arkivjar mixgħul, u timeline WAL ġdida tibda. Ħu backup bażi frisk minnufih.

L-isem tal-proġett quire jipprefigġi kull volum; docker volume ls juri l- ismijiet eżatti.

Id-drill tal-verifika skedata

backup-offsite imexxi wkoll drill kull QUIRE_BACKUP_DRILL_INTERVAL_HOURS (default 168, kull ġimgħa), u mill-ġdid fil-pass li jmiss wara li wieħed ifalli. Huwa jġib l-aktar backup bażi ġdid barra l-host u kull segment WAL warajh, jiddekripta kull wieħed (li jipprova li ċ-ċavetta xorta tiftaħhom u xejn ma ġie mibdul), iqabbel kull fajl mal-manifest tiegħu, jiċċekkja li l-arkivju huwa directory tad-data ta’ Postgres, u jiċċekkja li l-WAL mill-backup ’il quddiem m’għandu l-ebda vojt. Ir-rapport jinkiteb fil- maħżen bħala reports/drill-<time>.json u fil-log tas-servizz; drill fallut isemmi il-fajl jew l-ewwel segment nieqes.

Id-drill tar-restore

Backup li qatt ma ġie rrestawrat mhuwiex backup. Id-drill jirrestawra l- aktar backup bażi komplut ġdid meħud qabel il-mira, flimkien mal-arkivju WAL, f’Postgres scratch li ma jaqsam xejn mal-live, u jipprova r- riżultat:

docker/scripts/restore-drill.sh                                  # to ninety minutes ago
docker/scripts/restore-drill.sh --target "2026-09-24 09:30:00+00"

Il-mira hija UTC f’dik il-forma eżatta. Jeħtieġ backup bażi eqdem minnha u WAL arkivjat lil hinn minnha: fuq installazzjoni ġdida, ħu backup bażi u stenna għas- segment arkivjat li jmiss (l-aktar minuta bi kitbiet) qabel ma tagħżel mira wara l-backup. Id-drill jeħtieġ Docker u bash fuq il-host, xejn ieħor.

Kull pass ifalli d-drill:

  1. Irkuprabbiltà: il-cluster scratch jerġa’ jdoqq sal-mira u jiftaħ.
  2. Kompletezza: l-għadd tar-ringieli ta’ kull tabella kontra d-database live (tooling/restore-drill). Id-database live mexgħet ‘il quddiem mill-mira, għalhekk tabella tista’ tvarja bl-akbar ta’ 500 ringiela u għaxra tad-daqs tagħha, fi kull direzzjoni (kitbiet jagħmluha lura, tħassir jagħmel ir-restore jżomm aktar); partizzjoni maħluqa wara l-mira mhijiex tabella mitlufa. Wessa’ l- allowance fuq installazzjoni aktar traffikuża b’QUIRE_DRILL_MAX_BEHIND u QUIRE_DRILL_MAX_DRIFT_RATIO. Tabella nieqsa jew vojta tfalli.
  3. Integrità: il-katina hash tal-verifika tivverifika fuq il-kopja rrestawrata.
  4. Użabbiltà: ir-rwol tal-applikazzjoni jaqra permezz ta’ sigurtà fil-livell tar-ringieli.
  5. Ħin: mill-bidu għal aħdar, kontra QUIRE_DRILL_RTO_SECONDS (default 3600).

Qatt ma jikteb fid-database live jew fil-volumi tagħha: il-backup u l-WAL volumi huma mounted qari biss u l-cluster scratch jitneħħa fl-aħħar, jgħaddi jew ifalli.

Issettja QUIRE_DRILL_REPORT għal mogħdija biex rapport JSON jinkiteb, jgħaddi jew ifalli, u ħaddmu fuq skeda mill-host Docker:

30 3 1 * * cd /srv/quire && QUIRE_DRILL_REPORT=/var/log/quire-drill.json docker/scripts/restore-drill.sh >> /var/log/quire-drill.log 2>&1

Ħaddmu kull xahar u qabel kull aġġornament. Drill fallut jimblokka l-aġġornament. Darba kull tliet xhur, ħalli lil xi ħadd li ma kitebx dan ir-runbook iwettaq restore puntwal reali fuq host żejjed, bl-użu ta’ dan id-dokument biss.

Fajls

Fajls lokali jgħixu fil-volum files. Agħmel backup tagħhom mad-database, fl- istess ħin, u rrestawra t-tnejn flimkien:

docker run --rm -v quire_files:/files:ro -v "$PWD":/out alpine tar -czf /out/files-$(date -u +%Y%m%d).tar.gz -C /files .

B’ħażna ta’ oġġetti, ixgħel il-verżjonar tal-bucket u żomm 35 jum ta’ verżjonijiet mhux attwali; irkupru puntwal għall-fajls imbagħad huwa dak tal-bucket stess.

Navigazzjoni

Ittajpja biex tfittex…

↑↓ innaviga↵ agħżelEsc agħlaq