A kialakítást a docs/architecture/23-ops.md 8. szakasza írja le. Ez a Docker Compose-termék eljárásrendje. Úgy készült, hogy a műveletet olyan ember is végrehajthassa, aki nem írta; ha egy lépés nem világos, az a dokumentum hibája.
Mit védünk, és hogyan
Eszköz
Módszer
Hely
Adatbázis
Folyamatos WAL-archiválás, legfeljebb 60 másodpercenként, az első indítástól
pgwal kötet
Adatbázis
Alapmentések pg_basebackup használatával, alapértelmezés szerint naponta (backup-scheduler)
pgbackup kötet
Adatbázis
Az alapmentések és WAL titkosított másolata ötpercenként (backup-offsite)
Külön, Ön által megadott tároló
Fájlok
A files kötet. Másolja a host mentőeszközével, vagy használjon verziózott objektumtárolót
files kötet
Titkok
docker/.env, különösen az esetleg használt QUIRE_MASTER_KEY és QUIRE_MASTER_KEY_RETIRED, a QUIRE_BACKUP_ENCRYPTION_KEY és a docker/secrets/audit-signing-key.pem
Cél: a hiba előtti 60 másodpercen belüli helyreállítási pont, valamint 500 GB-os adatbázis visszaállítása 60 percen belül.
Két hiba gyakori. A fájljai nélkül visszaállított adatbázis hibás oldalakat eredményez. A QUIRE_MASTER_KEY nélkül visszaállított adatbázis nem tudja visszafejteni a benne lévő SSO-, webhook- és integrációs hitelesítő adatokat; amíg a kulcscsere minden megoldatlan elemtől mentesen be nem fejeződik (key-rotation.md), a visszavont kulcsokra is szükség van. Mindegyik a mentés részét képezi.
Biztonsági mentések készítése
Teljes fürt alapmentése:
docker compose -f docker/compose.yaml --profile backup run --rm backup
A legújabb QUIRE_BACKUP_KEEP számú alapmentést őrzi meg (alapértelmezés szerint 5), és törli azt a régi WAL-t, amelyre már nincs szükség, így az archívum nem nő korlátlanul. A hoston állítson be napi cron-feladatot vagy systemd időzítőt:
15 2 * * * cd /srv/quire && docker compose -f docker/compose.yaml --profile backup run --rm backup >> /var/log/quire-backup.log 2>&1
Vagy bízza az ütemezést a stackre: a backup profil elindítja a backup-scheduler szolgáltatást, amely minden QUIRE_BACKUP_INTERVAL_HOURS időközönként készít alapmentést (alapérték 24), valamint a következőként ismertetett backup-offsite szolgáltatást.
docker compose -f docker/compose.yaml --profile backup up -d
Titkosított másolatok külső hoston
Mindkét kötet ugyanazon a hoston található, mint az adatbázis; a meghibásodott gépen lévő mentés nem mentés. A backup-offsite minden alapmentést és archivált WAL-szegmenst titkosít, a storage-rétegen át külön tárolóba másol, majd megőrzési szabály szerint ott tárolja:
Titkosítás. AES-256-GCM a QUIRE_BACKUP_ENCRYPTION_KEY beállítással vagy a QUIRE_BACKUP_ENCRYPTION_KEY_FILE által megadott fájllal: 32 bájt, előállítása openssl rand -hex 32 paranccsal. Minden fájlnak külön nonce-a és hitelesítési címkéje van, ezért kulcs nélkül nem olvasható, módosítása pedig észlelhető. A kulcsot a QUIRE_MASTER_KEY mellett, a hosttól és mentéstárolótól külön őrizze. Kulcs nélkül nincs visszaállítás.
Hely. A QUIRE_BACKUP_STORAGE_DRIVER értéke s3, azure vagy local (csatolt távoli lemez a QUIRE_BACKUP_STORAGE_ROOT alatt). Használja a fájltárolás beállításait QUIRE_BACKUP_ előtaggal: QUIRE_BACKUP_S3_ENDPOINT, QUIRE_BACKUP_S3_BUCKET, QUIRE_BACKUP_S3_ACCESS_KEY_ID stb. Másik bucketet, lehetőleg másik fiókot használjon, és ha a szolgáltató engedi, olyan hitelesítő adatokat, amelyek írhatnak, de törölni nem tudnak.
Megőrzés. A legújabb QUIRE_BACKUP_OFFSITE_KEEP számú alapmentés (alapértelmezés a QUIRE_BACKUP_KEEP, ennek hiányában 7) és a legrégebbi mentéshez szükséges WAL marad meg; a régebbi készleteket és szegmenseket törli a tárolóból.
Ütemezés. Minden QUIRE_BACKUP_SHIP_INTERVAL_SECONDS másodpercben (alapérték 300). A küldés idempotens: a már tárolt elemek kimaradnak, az alapmentés pedig csak a jegyzék utolsóként történő megírása után számít tároltnak.
Ugyanez a parancs kézzel is futtatható:
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
Új hostra történő visszaállításhoz előbb töltsön vissza egy készletet, majd az alábbi lépéseknél a letöltött könyvtárat használja a pgbackup kötet, a letöltött wal-archive könyvtárat pedig a pgwal helyett:
bun apps/worker/src/backups/main.ts fetch base-20260924T021500Z /srv/restore
Visszaállítás egy adott időpontra
Adatvesztés után használja, például hibás import, törölt kurzus vagy visszavonandó szerződésmigráció esetén. Lecseréli az éles adatbázist, ezért előbb gyakorolja a lenti próbával.
Válassza ki a célidőpontot UTC-ben, közvetlenül a káresemény előtt: 2026-09-24 09:30:00+00. Az auditnapló (/admin/audit) rendszerint mutatja az időpontot.
Állítson le mindent, ami ír: docker compose -f docker/compose.yaml stop web content worker scheduler collab
Tartsa meg a sérült fürtöt a visszaállítás ellenőrzéséig:
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/
Csomagolja ki a célidőpontnál korábbi legújabb alapmentést az adatkönyvtárba, és kérjen célzott helyreállítást:
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'
Helyreállítás: indítsa el egyszer a Postgrest a helyreállítási beállításokkal, Compose felülíró fájlból, így a normál fájl érintetlen marad:
A felülírás lecseréli a teljes parancsot, ezért ismét tartalmaznia kell a helyreállításhoz szükséges két beállítást: a max_connections értéke ne legyen kisebb az elsődlegesénél (különben a helyreállítás „insufficient parameter settings” hibával leáll), és adja meg a csatolt pg_hba.conf fájlt is.
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"
Ellenőrizze, mielőtt bárkit visszaenged: auditlánc (docker compose -f docker/compose.yaml run --rm worker bun tooling/audit-verify/run.ts) és hogy az elveszett adat visszatért-e.
Térjen vissza a normál működéshez: docker compose -f docker/compose.yaml up -d. Ez archiválással indítja újra a Postgrest, új WAL-idővonal kezdődik. Azonnal készítsen új alapmentést.
A quire projektnevet minden kötet előtagként használja; a docker volume ls megmutatja a pontos neveket.
Ütemezett ellenőrzési próba
A backup-offsite minden QUIRE_BACKUP_DRILL_INTERVAL_HOURS időközönként (alapérték 168, hetente) próbát is futtat, sikertelenség után pedig a következő futásnál újrapróbálja. Letölti a legújabb külső alapmentést és az összes utána következő WAL-szegmenst, mindegyiket visszafejti (ezzel igazolja, hogy a kulcs működik, és semmi sem módosult), összeveti a fájlokat a jegyzékükkel, ellenőrzi, hogy az archívum Postgres-adatkönyvtár, és hogy az alapmentéstől nincs hiány a WAL-ban. A jelentés reports/drill-<time>.json néven kerül a tárolóba és a szolgáltatás naplójába; hiba esetén megnevezi a fájlt vagy első hiányzó szegmenst.
Visszaállítási próba
A még soha vissza nem állított mentés nem valódi mentés. A próba az éles adatbázistól teljesen különálló, ideiglenes Postgresbe állítja vissza a célidőpont előtti legújabb teljes alapmentést és a WAL-archívumot, majd igazolja az eredményt:
docker/scripts/restore-drill.sh # to ninety minutes agodocker/scripts/restore-drill.sh --target "2026-09-24 09:30:00+00"
A célidőpont UTC, pontosan ebben a formában. Kell hozzá korábbi alapmentés és az utána archivált WAL: új telepítésnél készítsen alapmentést, és várja meg a következő archivált szegmenst (írások mellett legfeljebb egy perc), mielőtt a mentés utáni időpontot választja. A próbához csak Docker és bash kell a hoston.
Bármelyik lépés sikertelensége megbuktatja a próbát:
Helyreállíthatóság: az ideiglenes fürt visszajátszik a célidőpontig, és megnyílik.
Teljesség: minden tábla sorszáma a jelenlegi adatbázishoz képest (tooling/restore-drill). Az élő adatbázis a cél óta változott, ezért egy tábla mindkét irányban eltérhet 500 sor vagy méretének egytizede közül a nagyobb értékkel (az írások miatt a visszaállítás lemarad, törlésnél több sora lehet); a cél után létrejött partíció nem számít hiányzó táblának. Forgalmasabb telepítésen bővítse az engedményt a QUIRE_DRILL_MAX_BEHIND és QUIRE_DRILL_MAX_DRIFT_RATIO értékeivel. Hiányzó vagy kiürült tábla esetén a próba megbukik.
Sértetlenség: az audit hash-lánc ellenőrzése sikerül a visszaállított példányon.
Használhatóság: az alkalmazásszerepkör row-level security mellett olvas.
Idő: az indulástól a sikerig eltelt idő a QUIRE_DRILL_RTO_SECONDS értékén belül van (alapérték 3600).
Soha nem ír az éles adatbázisba vagy köteteibe: a mentési és WAL-kötetek csak olvashatóan csatolódnak, az ideiglenes fürt pedig a végén törlődik, akár sikerült, akár nem.
Állítsa a QUIRE_DRILL_REPORT értékét egy útvonalra, ha siker vagy hiba esetén is JSON-jelentést szeretne, majd ütemezze a futtatást a Docker-hoston:
Futtassa havonta és minden frissítés előtt. Sikertelen próba esetén ne frissítsen. Negyedévente kérjen meg valakit, aki nem írta ezt az eljárást, hogy kizárólag e dokumentum alapján végezzen valódi, időpontra történő visszaállítást egy tartalék hoston.
Fájlok
A helyi fájlok a files kötetben találhatók. Ugyanakkor készítsen róluk mentést az adatbázissal, és állítsa vissza őket együtt:
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 .
Objektumtárolás esetén kapcsolja be a bucket verziózását, és 35 napig őrizze meg a nem aktuális verziókat; így a fájlok időpontra történő visszaállítását maga a bucket biztosítja.