Rakenne kuvataan tiedoston docs/architecture/23-ops.md kohdassa 8. Tämä on Docker Compose -tuotteen käyttöohje. Se on kirjoitettu henkilölle, joka ei ole kirjoittanut sitä. Jos jokin vaihe on epäselvä, ohjetta on korjattava.
Suojattavat tiedot ja suojaustavat
Kohde
Suojaustapa
Sijainti
Tietokanta
WAL-arkistointi enintään 60 sekunnin välein ensimmäisestä käynnistyksestä alkaen
pgwal-taltio
Tietokanta
Perusvarmuuskopiointi työkalulla pg_basebackup, oletuksena päivittäin (backup-scheduler)
pgbackup-taltio
Tietokanta
Salatut kopiot perusvarmuuskopioista ja WAL-tiedoista viiden minuutin välein (backup-offsite)
Erillinen määrittämäsi tallennuspaikka
Tiedostot
files-taltio. Kopioi isäntäkoneen varmuuskopiointityökalulla tai käytä versioitua objektitallennusta.
files-taltio
Salaisuudet
docker/.env, erityisesti QUIRE_MASTER_KEY (ja mahdollinen yhä käytössä oleva QUIRE_MASTER_KEY_RETIRED), QUIRE_BACKUP_ENCRYPTION_KEY sekä docker/secrets/audit-signing-key.pem
Säilytä kopio muualla kuin tällä isännällä
Hakuindeksit, välimuistit, versiotiedostot
Ei varmuuskopioida; luodaan uudelleen
Tavoitteet: palautuspiste on enintään 60 sekuntia ennen virhettä, ja 500 Gt:n tietokannan palautus kestää enintään 60 minuuttia.
Kaksi virhettä ovat yleisiä. Ilman tiedostoja palautettu tietokanta näyttää rikkinäisiä sivuja. Ilman QUIRE_MASTER_KEY-avainta palautettu tietokanta ei voi purkaa sen sisältämiä SSO-, webhook- ja integraatiotunnistetietoja. Kunnes pääavaimen kierrätys valmistuu ilman selvittämättömiä arvoja (key-rotation.md), tämä koskee myös vanhoja avaimia. Molemmat kuuluvat varmuuskopioon.
Varmuuskopioiden ottaminen
Perusvarmuuskopio koko klusterista:
docker compose -f docker/compose.yaml --profile backup run --rm backup
Se säilyttää uusimmat QUIRE_BACKUP_KEEP perusvarmuuskopiota (oletus 5) ja poistaa WAL-tiedot, joita vanhin säilytetty varmuuskopio ei enää tarvitse, jotta arkisto ei kasva rajattomasti. Ajasta varmuuskopiointi päivittäiseksi cron- tai systemd-ajastimella isännässä:
15 2 * * * cd /srv/quire && docker compose -f docker/compose.yaml --profile backup run --rm backup >> /var/log/quire-backup.log 2>&1
Voit myös antaa pinon ajastaa sen. backup-profiili käynnistää backup-scheduler-palvelun, joka ottaa perusvarmuuskopion QUIRE_BACKUP_INTERVAL_HOURS-asetuksen mukaan (oletus 24), sekä seuraavaksi kuvattavan backup-offsite-palvelun.
docker compose -f docker/compose.yaml --profile backup up -d
Salatut kopiot toisessa sijainnissa
Molemmat taltioita ovat samalla isännällä kuin tietokanta, eikä vioittuneella laitteella oleva varmuuskopio ole todellinen varmuuskopio. backup-offsite kopioi kaikki perusvarmuuskopiot ja arkistoidut WAL-segmentit salattuina erilliseen tallennuspaikkaan tallennusrajapinnan kautta ja säilyttää ne siellä säilytysasetusten mukaisesti:
Salaus. AES-256-GCM käyttää QUIRE_BACKUP_ENCRYPTION_KEY-arvoa tai muuttujassa QUIRE_BACKUP_ENCRYPTION_KEY_FILE määritettyä tiedostoa. Avaimen pituus on 32 tavua. Luo se komennolla openssl rand -hex 32. Jokaisella tiedostolla on oma nonce ja todennustunniste, joten kopio ei ole luettavissa ilman avainta ja kaikki muutokset havaitaan. Säilytä avain yhdessä QUIRE_MASTER_KEY-avaimen kanssa erillään isännästä ja varmuuskopioiden tallennuspaikasta. Ilman avainta tietoja ei voi palauttaa.
Sijainti.QUIRE_BACKUP_STORAGE_DRIVER voi olla s3, azure tai local (liitetty etälevy polussa QUIRE_BACKUP_STORAGE_ROOT). Asetukset vastaavat tiedostotallennuksen asetuksia QUIRE_BACKUP_-etuliitteellä: QUIRE_BACKUP_S3_ENDPOINT, QUIRE_BACKUP_S3_BUCKET, QUIRE_BACKUP_S3_ACCESS_KEY_ID ja niin edelleen. Käytä tiedostoista erillistä säilöä ja mieluiten erillistä tiliä sekä tunnistetietoja, joilla voi kirjoittaa mutta ei poistaa, jos palveluntarjoaja tukee sitä.
Säilytys. Säilytä uusimmat QUIRE_BACKUP_OFFSITE_KEEP perusvarmuuskopiota (oletuksena QUIRE_BACKUP_KEEP tai 7) ja vanhimman niistä tarvitsema WAL. Vanhemmat varmuuskopiot ja segmentit poistetaan tallennuspaikasta.
Ajoitus. Kopioi tiedot QUIRE_BACKUP_SHIP_INTERVAL_SECONDS-asetuksen mukaan (oletus 300 sekuntia). Siirto on idempotentti: ennestään tallennetut tiedot ohitetaan, ja perusvarmuuskopio merkitään valmiiksi vasta sitten, kun sen luettelo on viimeisenä kirjoitettu.
Samat komennot voi suorittaa käsin:
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
Palauta tiedot uudelle isännälle hakemalla ensin varmuuskopio. Noudata sen jälkeen alla olevia vaiheita niin, että käytät haettua hakemistoa pgbackup-taltion sijasta ja haettua wal-archive-hakemistoa pgwal-taltion sijasta:
bun apps/worker/src/backups/main.ts fetch base-20260924T021500Z /srv/restore
Palautus tiettyyn ajanhetkeen
Käytä tätä tietojen katoamiseen, esimerkiksi virheelliseen tuontiin, poistettuun kurssiin tai peruttavaan poistomigraatioon. Toiminto korvaa aktiivisen tietokannan, joten harjoittele ensin alla olevalla harjoituksella.
Valitse kohdeaika UTC-ajassa juuri ennen vahinkoa: 2026-09-24 09:30:00+00. Ajankohta näkyy yleensä auditointilokissa (/admin/audit).
Pysäytä kaikki kirjoittavat palvelut: docker compose -f docker/compose.yaml stop web content worker scheduler collab.
Säilytä vaurioitunut klusteri, kunnes palautus on tarkistettu:
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/
Pura uusin kohdeaikaa vanhempi perusvarmuuskopio tietotaltiolle ja ota kohdennettu palautus käyttöön:
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'
Palauta tiedot käynnistämällä Postgres kerran palautusasetuksilla Compose-korvaustiedoston kautta. Tavalliseen tiedostoon ei tehdä muutoksia:
Korvaustiedosto asettaa koko komennon uudelleen, joten se sisältää molemmat palautuksen edellyttämät asetukset: max_connections ei saa olla pienempi kuin ensisijaisessa tietokannassa (muuten palautus keskeytyy virheellä “insufficient parameter settings”) ja liitetty pg_hba.conf-tiedosto.
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"
Tarkista palautus, ennen kuin päästät käyttäjät takaisin: tarkista auditointiketju komennolla docker compose -f docker/compose.yaml run --rm worker bun tooling/audit-verify/run.ts ja varmista, että kadonneet tiedot ovat palautuneet.
Palauta normaali toiminta komennolla docker compose -f docker/compose.yaml up -d. Se käynnistää Postgresin arkistointi päällä ja aloittaa uuden WAL-aikajanan. Ota heti uusi perusvarmuuskopio.
Projektin nimi quire lisätään jokaisen taltion alkuun. Tarkat nimet näet komennolla docker volume ls.
Ajastettu varmennusharjoitus
backup-offsite suorittaa harjoituksen myös QUIRE_BACKUP_DRILL_INTERVAL_HOURS-asetuksen mukaan (oletus 168 eli viikoittain). Epäonnistunut harjoitus yritetään uudelleen seuraavalla ajolla. Palvelu hakee uusimman toisessa sijainnissa olevan perusvarmuuskopion ja sitä seuraavat WAL-segmentit, purkaa kunkin salauksen (näin varmistuu, että avain toimii eikä tietoja ole muutettu), vertaa tiedostoja luetteloon, tarkistaa arkiston Postgres-tietohakemistoksi ja varmistaa, ettei WAL-virrassa ole aukkoja varmuuskopiosta eteenpäin. Raportti tallennetaan sijaintiin nimellä reports/drill-<time>.json ja palvelun lokiin. Epäonnistuneessa harjoituksessa nimetään tiedosto tai ensimmäinen puuttuva segmentti.
Palautusharjoitus
Varmuuskopio, jota ei ole koskaan palautettu, ei ole varmuuskopio. Harjoitus palauttaa uusimman täydellisen kohdeaikaa edeltävän perusvarmuuskopion ja WAL-arkiston erilliseen, aktiivisen tietokannan kanssa mitään jakamattomaan Postgres-kokeiluympäristöön ja todistaa tuloksen:
docker/scripts/restore-drill.sh # to ninety minutes agodocker/scripts/restore-drill.sh --target "2026-09-24 09:30:00+00"
Kohdeaika annetaan UTC-muodossa täsmälleen tällä tavalla. Tarvitaan kohdeaikaa vanhempi perusvarmuuskopio ja sen jälkeinen arkistoitu WAL. Ota uudessa asennuksessa perusvarmuuskopio ja odota seuraavan arkistoidun segmentin valmistumista (kirjoitettaessa enintään minuutti) ennen kohdeajan asettamista varmuuskopion jälkeen. Harjoitus edellyttää isännässä vain Dockeria ja bashia.
Harjoitus epäonnistuu, jos jokin seuraavista vaiheista epäonnistuu:
Palautettavuus: kokeiluklusteri palauttaa tiedot kohdeaikaan ja käynnistyy.
Täydellisyys: jokaisen taulun rivimäärät verrataan aktiiviseen tietokantaan (tooling/restore-drill). Aktiivinen tietokanta on ehtinyt muuttua kohdeajan jälkeen, joten ero saa kumpaankin suuntaan olla enintään suurempi arvoista: 500 riviä tai kymmenesosa taulun koosta. Kirjoitukset vähentävät rivimäärää, poistot lisäävät palautettujen rivien määrää. Kohdeajan jälkeen luotu osio ei ole kadonnut taulu. Kasvata sallittua eroa vilkkaassa asennuksessa muuttujilla QUIRE_DRILL_MAX_BEHIND ja QUIRE_DRILL_MAX_DRIFT_RATIO. Puuttuva tai tyhjä taulu johtaa aina epäonnistumiseen.
Käytettävyys: sovellusrooli pystyy lukemaan tietoja rivikohtaisen tietoturvan läpi.
Aika: käynnistyksestä onnistumiseen kuluu enintään QUIRE_DRILL_RTO_SECONDS-arvon verran (oletus 3600 sekuntia).
Harjoitus ei kirjoita aktiiviseen tietokantaan eikä sen taltioihin. Varmuuskopio- ja WAL-taltiot liitetään vain luku -muodossa, ja kokeiluklusteri poistetaan lopuksi riippumatta onnistumisesta.
Aseta QUIRE_DRILL_REPORT-muuttujalle polku, jos haluat JSON-raportin sekä onnistumisesta että epäonnistumisesta. Ajasta harjoitus Docker-isännässä:
Suorita harjoitus kuukausittain ja ennen jokaista päivitystä. Epäonnistunut harjoitus estää päivityksen. Anna neljännesvuosittain henkilön, joka ei kirjoittanut tätä ohjetta, suorittaa oikea ajanhetkipalautus varaisännälle pelkästään tämän dokumentin avulla.
Tiedostot
Paikalliset tiedostot sijaitsevat files-taltiossa. Varmuuskopioi se tietokannan kanssa samaan aikaan ja palauta molemmat yhdessä:
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 .
Jos käytät objektitallennusta, ota säilön versiointi käyttöön ja säilytä vanhentuneet versiot 35 päivän ajan. Tällöin tiedostojen ajanhetkipalautuksen hoitaa säilön oma versiointi.