Dizajn je opisan u odjeljku 8 dokumenta docs/architecture/23-ops.md. Ovo je
operativni priručnik za proizvod Docker Compose. Napisana je tako da je može
slijediti i osoba koja je nije sastavila; ako je neki korak nejasan, to je
nedostatak ovog dokumenta.
Što je zaštićeno i kako
Sredstvo
Način zaštite
Mjesto
Baza podataka
WAL se kontinuirano arhivira, najviše svakih 60 sekundi, od prvog pokretanja
Volumen pgwal
Baza podataka
Osnovne kopije pomoću pg_basebackup, zadano svakodnevno (backup-scheduler)
Volumen pgbackup
Baza podataka
Šifrirane kopije osnovnih sigurnosnih kopija i WAL-a svakih pet minuta (backup-offsite)
Odvojeno spremište koje navedete
Datoteke
Volumen files. Kopirajte ga alatom za sigurnosne kopije poslužitelja ili koristite pohranu objekata s verzijama
Volumen files
Tajne
docker/.env, a osobito QUIRE_MASTER_KEY (i sve povučene vrijednosti QUIRE_MASTER_KEY_RETIRED koje se još koriste), QUIRE_BACKUP_ENCRYPTION_KEY i docker/secrets/audit-signing-key.pem
Ne izrađuju se sigurnosne kopije; ponovno se stvaraju
Ciljevi su točka oporavka unutar 60 sekundi prije kvara i vraćanje u roku od
60 minuta za bazu veličine 500 GB.
Dvije su pogreške česte. Vraćena baza bez datoteka prikazuje neispravne
stranice. Vraćena baza bez QUIRE_MASTER_KEY ne može dešifrirati
vjerodajnice SSO-a, web-dojavnika i integracija koje sadrži; sve dok se
rotacija glavnog ključa ne dovrši bez nerazriješenih stavki
(key-rotation.md), to uključuje i povučene ključeve. Obje
stavke dio su sigurnosne kopije.
Izrada sigurnosnih kopija
Osnovna sigurnosna kopija cijelog skupa:
docker compose -f docker/compose.yaml --profile backup run --rm backup
Zadržava najnovijih QUIRE_BACKUP_KEEP osnovnih kopija (zadano 5) i briše WAL
koji najstarijoj više nije potreban, pa arhiva ne može neograničeno rasti.
Zakažite svakodnevno pokretanje naredbom cron ili mjeračem systemd na
poslužitelju:
15 2 * * * cd /srv/quire && docker compose -f docker/compose.yaml --profile backup run --rm backup >> /var/log/quire-backup.log 2>&1
Ili prepustite zakazivanje samom skupu usluga: profil backup pokreće
backup-scheduler, koji izrađuje osnovnu kopiju svakih
QUIRE_BACKUP_INTERVAL_HOURS sati (zadano 24), te backup-offsite, opisan u
nastavku.
docker compose -f docker/compose.yaml --profile backup up -d
Šifrirane kopije izvan poslužitelja
Oba su volumena na istom poslužitelju kao baza, a sigurnosna kopija na stroju
koji je otkazao nije sigurnosna kopija. backup-offsite kopira svaku osnovnu
kopiju i svaki arhivirani segment WAL-a kroz priključak za pohranu u odvojeno,
šifrirano spremište te ondje primjenjuje pravila zadržavanja:
Šifriranje. AES-256-GCM s ključem QUIRE_BACKUP_ENCRYPTION_KEY (ili
datotekom navedenom u QUIRE_BACKUP_ENCRYPTION_KEY_FILE): 32 bajta,
generirana naredbom openssl rand -hex 32. Svaka datoteka ima vlastiti
nonce i oznaku provjere autentičnosti, pa se kopija ne može pročitati bez
ključa i otkrivaju se sve njezine izmjene. Ključ čuvajte uz
QUIRE_MASTER_KEY, podalje od ovog poslužitelja i spremišta sigurnosnih
kopija. Bez ključa nema vraćanja.
Mjesto.QUIRE_BACKUP_STORAGE_DRIVER može biti s3, azure ili local
(udaljeni disk priključen na QUIRE_BACKUP_STORAGE_ROOT). Postavke su jednake
onima za pohranu datoteka uz prefiks QUIRE_BACKUP_:
QUIRE_BACKUP_S3_ENDPOINT, QUIRE_BACKUP_S3_BUCKET,
QUIRE_BACKUP_S3_ACCESS_KEY_ID i druge. Koristite drugi spremnik i, po
mogućnosti, drugi račun od onoga za datoteke, s vjerodajnicama koje mogu
zapisivati, ali ne i brisati, ako pružatelj to podržava.
Zadržavanje. Zadržavaju se najnovijih QUIRE_BACKUP_OFFSITE_KEEP
osnovnih kopija (zadano je QUIRE_BACKUP_KEEP, a ako ni ono nije postavljeno,
vrijednost je 7) te WAL potreban najstarijoj od njih; stariji skupovi i
segmenti brišu se iz spremišta.
Učestalost. Svakih QUIRE_BACKUP_SHIP_INTERVAL_SECONDS sekundi (zadano
300). Slanje je idempotentno: već pohranjene stavke preskaču se, a osnovna
kopija smatra se pohranjenom tek nakon što se kao posljednji korak zapiše
njezin manifest.
Ista se naredba može pokrenuti ručno:
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
Za vraćanje na novi poslužitelj najprije preuzmite skup, a zatim slijedite
korake u nastavku tako da preuzeti direktorij zamijeni volumen pgbackup, a
preuzeti wal-archive volumen pgwal:
bun apps/worker/src/backups/main.ts fetch base-20260924T021500Z /srv/restore
Vraćanje na određeni trenutak
Primijenite postupak nakon gubitka podataka: neispravnog uvoza, izbrisanog
kolegija ili migracije uklanjanja koju morate poništiti. Njime se zamjenjuje
aktivna baza, pa ga najprije uvježbajte probom u nastavku.
Odaberite ciljno vrijeme u UTC-u, neposredno prije oštećenja:
2026-09-24 09:30:00+00. Trenutak je obično vidljiv u zapisu nadzora
(/admin/audit).
Zaustavite sve procese koji zapisuju:docker compose -f docker/compose.yaml stop web content worker scheduler collab
Zadržite oštećeni skup dok se ne provjeri vraćena baza:
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/
Raspakirajte najnoviju osnovnu sigurnosnu kopiju nastalu prije ciljnog
vremena u volumen podataka i zatražite oporavak do odabrane točke:
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'
Provedite oporavak: pokrenite Postgres jednom s postavkama oporavka iz
dodatne Compose datoteke kako biste ostavili uobičajenu datoteku
nepromijenjenom:
Dodatna datoteka zamjenjuje cijelu naredbu, pa ponavlja obje postavke
potrebne za oporavak: max_connections mora biti barem jednak vrijednosti
na primarnoj bazi (inače oporavak završava uz poruku „insufficient parameter
settings”), a uključena mora biti i priključena datoteka 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"
Provjerite bazu prije nego što ikoga pustite u nju: provjerite lanac
nadzora naredbom
docker compose -f docker/compose.yaml run --rm worker bun tooling/audit-verify/run.ts
i potvrdite da su izgubljeni podaci vraćeni.
Vratite uobičajeni rad:docker compose -f docker/compose.yaml up -d.
Postgres će se ponovno pokrenuti s uključenim arhiviranjem i započet će nova
vremenska linija WAL-a. Odmah izradite novu osnovnu sigurnosnu kopiju.
Naziv projekta quire prefiks je svakog volumena; točne nazive prikazuje
docker volume ls.
Zakazana proba provjere
backup-offsite također provodi probu svakih
QUIRE_BACKUP_DRILL_INTERVAL_HOURS sati (zadano 168, odnosno jednom tjedno),
a neuspješnu ponavlja već u sljedećem ciklusu. Dohvaća najnoviju osnovnu
sigurnosnu kopiju izvan poslužitelja i sve WAL segmente nakon nje, dešifrira ih
(čime potvrđuje da ih ključ još može otvoriti i da nisu izmijenjeni), uspoređuje
svaku datoteku s njezinim manifestom, provjerava da je arhiva direktorij
podataka Postgresa te potvrđuje da u WAL-u nakon sigurnosne kopije nema
prekida. Izvješće zapisuje u spremište kao reports/drill-<time>.json i u
zapis usluge; neuspješna proba navodi datoteku ili prvi nedostajući segment.
Proba vraćanja
Sigurnosna kopija koja nikad nije vraćena nije provjerena sigurnosna kopija.
Ova proba vraća najnoviju potpunu osnovnu sigurnosnu kopiju nastalu prije
ciljnog vremena, zajedno s arhivom WAL-a, u pomoćnu bazu Postgresa koja ne
dijeli ništa s aktivnom bazom te provjerava rezultat:
docker/scripts/restore-drill.sh # to ninety minutes agodocker/scripts/restore-drill.sh --target "2026-09-24 09:30:00+00"
Ciljno vrijeme mora biti UTC i zapisano upravo u tom obliku. Potrebna je
osnovna sigurnosna kopija starija od cilja i arhivirani WAL nakon njega: na
novoj instalaciji izradite osnovnu kopiju i pričekajte sljedeći arhivirani
segment (najviše minutu uz zapise) prije nego što odaberete kasnije ciljno
vrijeme. Proba na poslužitelju zahtijeva samo Docker i bash, ništa drugo.
Proba završava neuspjehom u svakom od sljedećih slučajeva:
Mogućnost oporavka: pomoćni se skup vrati do ciljnog trenutka i otvori.
Cjelovitost: usporede se brojevi redaka svih tablica sa živom bazom
(tooling/restore-drill). Aktivna baza odmaknula se od ciljnog vremena,
pa se tablica može razlikovati u oba smjera za veću od vrijednosti 500
redaka i jedne desetine njezine veličine (zapisi mogu značiti da vraćena
baza zaostaje, a brisanja da ih ima više); particija stvorena nakon ciljnog
vremena ne smatra se izgubljenom tablicom. Na aktivnijoj instalaciji
dopušteno odstupanje povećajte postavkama QUIRE_DRILL_MAX_BEHIND i
QUIRE_DRILL_MAX_DRIFT_RATIO. Nedostajuća ili ispražnjena tablica uzrokuje
neuspjeh.
Cjelovitost podataka: provjerava se lanac sažetaka nadzora na vraćenoj kopiji.
Upotrebljivost: uloga aplikacije može čitati podatke uz sigurnost na razini retka.
Vrijeme: trajanje od početka do uspješnog završetka uspoređuje se s
QUIRE_DRILL_RTO_SECONDS (zadano 3600).
Proba nikad ne zapisuje u aktivnu bazu ni njezine volumene: volumeni
sigurnosnih kopija i WAL-a priključuju se samo za čitanje, a pomoćni se skup
uklanja na kraju, bilo da je proba uspjela ili nije.
Postavite QUIRE_DRILL_REPORT na putanju za zapisivanje JSON izvješća i pri
uspjehu i pri neuspjehu, pa pokrenite probu po rasporedu s domaćina Dockera:
Pokrećite je mjesečno i prije svake nadogradnje. Neuspjela proba zaustavlja
nadogradnju. Jednom tromjesečno neka stvarni oporavak na određeni trenutak na
pomoćnom poslužitelju provede osoba koja nije napisala ovaj priručnik, služeći
se samo ovim dokumentom.
Datoteke
Lokalne se datoteke nalaze u volumenu files. Izradite njihovu sigurnosnu
kopiju istodobno s kopijom baze i zajedno ih vratite:
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 .
Uz pohranu objekata uključite izradu verzija spremnika i zadržite zastarjele
verzije 35 dana; vraćanje datoteka na određeni trenutak tada se obavlja
izvornim mehanizmom spremnika.