Arhitektuur on kirjeldatud dokumendi docs/architecture/23-ops.md jaotises 8.
See on Docker Compose’i toote juhend. Juhend on kirjutatud inimesele, kes seda
ise ei koostanud; iga ebaselge samm on puudus dokumendis.
Mis on kaitstud ja kuidas
Vara
Kuidas
Kus
Andmebaas
WAL arhiveeritakse pidevalt, kuni 60-sekundiliste vahedega, esimesest käivitusest alates
pgwal köide
Andmebaas
Põhi-varukoopiad pg_basebackup-iga, vaikimisi kord päevas (backup-scheduler)
pgbackup köide
Andmebaas
Põhi-varukoopiate ja WAL-i krüptitud koopiad iga viie minuti järel (backup-offsite)
Sinu määratud eraldi hoidla
Failid
files-köide. Kopeeri see hosti varundustööriistaga või kasuta versioonitud objektisalvestust
files-köide
Saladused
docker/.env, eriti QUIRE_MASTER_KEY (ja kasutusel olev QUIRE_MASTER_KEY_RETIRED), QUIRE_BACKUP_ENCRYPTION_KEY ning docker/secrets/audit-signing-key.pem
Hoia koopiat hostist eemal
Otsinguindeksid, vahemälud, teisendatud failid
Ei varundata; ehitatakse uuesti
Eesmärgid: rikke korral taastamispunkt kuni 60 sekundi kaugusel ning 500 GB
andmebaasi taastamine kuni 60 minutiga.
Kaks viga korduvad sageli. Andmebaasi taastamisel ilma failideta kuvatakse
katkiseid lehti. Andmebaas, mis taastati ilma QUIRE_MASTER_KEY-ta, ei saa
dekrüptida salvestatud SSO, veebikonksu ja integratsiooni mandaate; kuni peavõtme
vahetamine on lõpetatud nii, et midagi pole lahendamata
(key-rotation.md), kehtib see ka pensionile jäetud võtmete kohta.
Varunda mõlemad.
Varundamine
Tee kogu klastrist põhi-varukoopia:
docker compose -f docker/compose.yaml --profile backup run --rm backup
Alles jäetakse uusimad QUIRE_BACKUP_KEEP varukoopiad (vaikimisi 5) ning
kustutatakse vanimale enam mittevajalik WAL, et arhiiv piiramatult ei kasvaks.
Ajasta hostis igapäevane käivitus croni või systemd taimeriga:
15 2 * * * cd /srv/quire && docker compose -f docker/compose.yaml --profile backup run --rm backup >> /var/log/quire-backup.log 2>&1
Või lase virnal ajastada: backup-profiil käivitab backup-scheduleri, mis teeb
põhi-varukoopia iga QUIRE_BACKUP_INTERVAL_HOURS järel (vaikimisi 24) ning
järgmises jaotises kirjeldatud backup-offsitei.
docker compose -f docker/compose.yaml --profile backup up -d
Krüptitud koopiad väljaspool hosti
Mõlemad köited asuvad andmebaasiga samas hostis, seega rikkis masina varukoopia
pole päris varukoopia. backup-offsite kopeerib iga põhi-varukoopia ja arhiveeritud
WAL-i segmendi üle salvestuspordi krüptitult eraldi hoidlasse ning rakendab
säilitusreeglit:
Krüptimine. AES-256-GCM võtmega QUIRE_BACKUP_ENCRYPTION_KEY või faili
QUIRE_BACKUP_ENCRYPTION_KEY_FILE abil: 32 baiti, loodud käsuga
openssl rand -hex 32. Igal failil on oma nonce ja autentimismärgend, seega
pole koopiat võtmeta võimalik lugeda ning muudatus tuvastatakse. Hoia võtit koos
QUIRE_MASTER_KEY-ga sellest hostist ja varundushoidlast eraldi. Võtmeta ei saa
taastada.
Asukoht.QUIRE_BACKUP_STORAGE_DRIVER on s3, azure või local
(ühendatud kaugketas aadressil QUIRE_BACKUP_STORAGE_ROOT). Seaded on samad mis
failisalvestusel, kuid eesliitega QUIRE_BACKUP_: QUIRE_BACKUP_S3_ENDPOINT,
QUIRE_BACKUP_S3_BUCKET, QUIRE_BACKUP_S3_ACCESS_KEY_ID jne. Kasuta failidest
eraldi ämbrit ja võimalusel eraldi kontot; luba kirjutamine, kuid võimalusel
keela pakkuja seadetes kustutamine.
Säilitamine. Uusimad QUIRE_BACKUP_OFFSITE_KEEP põhi-varukoopiad (vaikimisi
QUIRE_BACKUP_KEEP, muidu 7) ja vanimale neist vajalik WAL; vanemad kogumid
ja segmendid kustutatakse hoidlast.
Millal. Iga QUIRE_BACKUP_SHIP_INTERVAL_SECONDS järel (vaikimisi 300).
Edastus on korduskindel: juba salvestatud failid jäetakse vahele ning
põhi-varukoopia loetakse talletatuks alles siis, kui manifest on viimaks kirjutatud.
Käsitsi käitatakse sama käsku:
docker compose -f docker/compose.yaml run --rm backup-offsite bun apps/worker/src/backups/main.ts shipdocker compose -f docker/compose.yaml run --rm backup-offsite bun apps/worker/src/backups/main.ts verify
Uues hostis taastamiseks too varukoopiate komplekt esmalt tagasi ja järgi allpool
olevaid samme; kasuta toodud kataloogi pgbackup-köite ning toodud wal-archive
kausta pgwal-köite asemel:
bun apps/worker/src/backups/main.ts fetch base-20260924T021500Z /srv/restore
Taastamine ajahetke seisundisse
Kasuta seda andmekao järel: vigane import, kustutatud kursus või tagasivõtmist
vajav andmebaasimuudatus. See asendab aktiivse andmebaasi, seega harjuta esmalt
allpool oleva taastamiskatsega.
Vali sihtaeg UTC-s, vahetult enne kahju:
2026-09-24 09:30:00+00. Tavaliselt näitab hetke auditi logi
(/admin/audit).
Peata kõik kirjutavad teenused:
docker compose -f docker/compose.yaml stop web content worker scheduler collab
Hoia kahjustatud klaster alles, kuni taastamine on kontrollitud:
docker compose -f docker/compose.yaml stop postgresdocker run --rm -v quire_postgres18-data:/from -v quire_postgres-damaged:/to alpine cp -a /from/. /to/
Paki sihtajast vanim uusim põhi-varukoopia andmeköitesse lahti ja palu
teha sihitud taastamine:
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'
Taasta: käivita Postgres üks kord taasteseadetega, kasutades
ülekirjutusfaili, et tavapärane fail jääks muutmata:
Ülekirjutus asendab kogu käsu, nii et taasteks tuleb lisada kaks vajalikku
seadet: max_connections peab olema vähemalt esmase väärtus (muidu katkeb
taastamine veaga “insufficient parameter settings”) ning määrata tuleb
ühendatud pg_hba.conf.
docker compose -f docker/compose.yaml -f docker/compose.recover.yaml up -d postgresdocker compose -f docker/compose.yaml logs -f postgres # wait for "database system is ready"
Kontrolli enne kellegi sisselaskmist auditi ahelat
(docker compose -f docker/compose.yaml run --rm worker bun tooling/audit-verify/run.ts)
ning veendu, et kadunud andmed on tagasi.
Taastu tavakäiduks: docker compose -f docker/compose.yaml up -d.
Postgres käivitub arhiveerimisega uuesti ja algab uus WAL-i ajajoon. Tee kohe
värske põhi-varukoopia.
Projektinimi quire lisatakse iga köite ette; täpseid nimesid näitab
docker volume ls.
Ajastatud kontrollkatse
backup-offsite käivitab katse iga QUIRE_BACKUP_DRILL_INTERVAL_HOURS järel
(vaikimisi 168 tundi ehk kord nädalas) ning pärast nurjumist kohe järgmisel
käivitusel uuesti. See hangib uusima hostivälise põhi-varukoopia ja sellele
järgnevad WAL-i segmendid, dekrüptib need (kontrollides, et võti neid avab ja
neid pole muudetud), võrdleb faile manifestiga, kontrollib arhiivi kui Postgresi
andmekataloogi ning veendub, et varukoopiale järgnev WAL on terviklik. Aruanne
salvestatakse hoidlas nimega reports/drill-<time>.json ja teenuse logis; nurjunud
katse nimetab faili või esimest puuduvat segmenti.
Taastamiskatse
Varukoopia, mida pole kunagi taastatud, pole tõestatud varukoopia. Katse taastab
uusima täieliku sihtajale eelnenud põhi-varukoopia koos WAL-arhiiviga ajutisse
Postgresesse, mis ei jaga aktiivsega midagi, ning kontrollib tulemust:
docker/scripts/restore-drill.sh # to ninety minutes agodocker/scripts/restore-drill.sh --target "2026-09-24 09:30:00+00"
Sihtaeg peab olema täpselt sellises UTC-vormingus. Vajalik on sellest varasem
põhi-varukoopia ja sellele järgnev arhiveeritud WAL: uuel paigaldusel tee
põhi-varukoopia ja oota enne hilisema sihtaja valimist järgmist arhiveeritud
segmenti (kirjutuste korral kõige rohkem minut). Katseks on hostis vaja üksnes
Dockerit ja bashi.
Iga samm võib katse nurjata:
Taastatavus: ajutine klaster taasesitab andmed sihtajani ja avaneb.
Täielikkus: iga tabeli ridade arvu võrreldakse aktiivse andmebaasiga
(tooling/restore-drill). Aktiivne andmebaas on sihtajast edasi liikunud,
seega võib tabelite ridade arv mõlemas suunas erineda suuremal väärtusel kahest:
500 rida või kümnendik tabeli suurusest (kirjutused tekitavad mahajäämust,
kustutused jätavad taastatud koopias rohkem ridu); pärast sihtaega loodud
sektsioon pole kadunud tabel. Suurema liiklusega paigaldises suurenda lubatud
vahet muutujatega QUIRE_DRILL_MAX_BEHIND ja QUIRE_DRILL_MAX_DRIFT_RATIO.
Puuduv või tühjaks jäänud tabel tähendab nurjumist.
Kasutatavus: rakenduseroll saab lugeda rea-taseme turbe kaudu.
Aeg: käivitamisest eduni kuluv aeg jääb QUIRE_DRILL_RTO_SECONDS
piiridesse (vaikimisi 3600).
Katse ei kirjuta kunagi aktiivsesse andmebaasi ega selle köidetesse: varukoopia-
ja WAL-köited ühendatakse kirjutuskaitstult ning ajutine klaster eemaldatakse
lõpus nii edu kui ka nurjumise korral.
Määra QUIRE_DRILL_REPORT aruandefaili asukohaks, et JSON kirjutataks nii edu
kui ka nurjumise korral, ning ajasta hosti Dockeris:
Käivita seda iga kuu ja enne iga uuendust. Nurjunud katse takistab uuendamist.
Kord kvartalis palu inimesel, kes juhendit ei kirjutanud, teha päris ajahetke
taastamine varuhostis ainult selle dokumendi põhjal.
Failid
Kohalikud failid paiknevad files-köites. Varunda need andmebaasiga samal ajal
ning taasta mõlemad koos:
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 .
Objektisalvestuse korral lülita sisse ämbri versioonimine ja säilita vanu
versioone 35 päeva; siis haldab failide ajahetke taastamist ämber ise.