Consilium est docs/architecture/23-ops.md sectio 8. Hic est liber operum
pro producti Docker Compose. Scriptus est ut ab eo sequatur qui eum non scripsit;
si aliquis gradus obscurus est, id vitium in hoc documentum est.
Quid tueatur, et quomodo
Res
Quomodo
Ubi
Bases datae
WAL continue archivata, omni 60 secunda saltem, ex prima incursione
volumen pgwal
Bases datae
Custodiae base cum pg_basebackup, cotidie per pristinum (backup-scheduler)
volumen pgbackup
Bases datae
Copiae encryptatae custodiarum base et WAL, omni quinque minuto (backup-offsite)
Receptor separatus quem tu nominas
Filetuli
Volumen files. Eum cum instrumento custodiae hospitis tui copia, aut repositionem obiectorum versionibus instructam utere
volumen files
Arcana
docker/.env, omnibus praecipue QUIRE_MASTER_KEY (et quodlibet QUIRE_MASTER_KEY_RETIRED adhuc in usu), QUIRE_BACKUP_ENCRYPTION_KEY, et docker/secrets/audit-signing-key.pem
Copiam extra hunc hostem serva
Indices quaestionis, thesauri, renditiones
Non custodiuntur; reficiuntur
Metae: punctum recuperationis intra 60 secundas ruinae, et restitutio intra 60
minuta pro basibus datae 500 GB.
Duo errorus communis sunt. Bases datae sine suis filetulis restitutae paginas
fractas reddit. Bases datae sine QUIRE_MASTER_KEY restitutae arcana SSO,
retextoris et integrationum quae tenet dechiffrare non possunt; usque ad id cum
rota clavis magistralis absoluta est nihilque inresolverum
(key-rotation.md), haec claves retiras includit. Utraque
partes custodiae sunt.
Custodias capere
Custodia base totius agminis:
docker compose -f docker/compose.yaml --profile backup run --rm backup
Ea novissimas QUIRE_BACKUP_KEEP custodias base servat (pristinum 5) et WAL quam
vetustissima non iam desiderat putat, ita ut archivum sine fine crescere non
possit. Eam cotidie cum cron aut timer systemd in hospite constitue:
15 2 * * * cd /srv/quire && docker compose -f docker/compose.yaml --profile backup run --rm backup >> /var/log/quire-backup.log 2>&1
Aut sine strue eam constituere sine: profilum backup currit backup-scheduler,
qui custodiam base omni QUIRE_BACKUP_INTERVAL_HOURS (pristinum 24) accipit,
et backup-offsite, qui proxime describitur.
docker compose -f docker/compose.yaml --profile backup up -d
Copiae extra hospitum encryptatae
Utraque volumina in eodem hospite cum basibus datae vivunt, et custodia in machina
quae ruit non est custodia. backup-offsite quamque custodiam base et omne
segmentum WAL archivatum per portum repositionis in receptorem separatum copiat,
encryptatum, et eos ibi sub retentione servat:
Encryptio. AES-256-GCM cum QUIRE_BACKUP_ENCRYPTION_KEY (aut filetulo a
QUIRE_BACKUP_ENCRYPTION_KEY_FILE nominato): 32 byta, ex
openssl rand -hex 32. Quisque filetulus suum nonce et notam authenticationis
habet, ideo copia sine clave legi nequit et quaelibet eius mutatio deprehenditur.
Clavem cum QUIRE_MASTER_KEY serva, longe ab hoc hospite et longe a receptore
custodiae. Sine clave nulla restitutio est.
Ubi.QUIRE_BACKUP_STORAGE_DRIVER est s3, azure aut local (discus
remotus adfixus in QUIRE_BACKUP_STORAGE_ROOT). Constitutiones eae sunt
filetulorum repositionis cum praefixo QUIRE_BACKUP_: QUIRE_BACKUP_S3_ENDPOINT,
QUIRE_BACKUP_S3_BUCKET, QUIRE_BACKUP_S3_ACCESS_KEY_ID, et ita porro. Bucket
diversum et, optime, rationem diversam a filetulis utere, cum credentiis quae
scribere possint non delere si praebitor permittit.
Retentio. Novissimae QUIRE_BACKUP_OFFSITE_KEEP custodiae base (pristinum
QUIRE_BACKUP_KEEP, alioquin 7) et WAL quam vetustissima earum desiderat;
antiquiores seti et segmenta e receptore delentur.
Quando. Omne QUIRE_BACKUP_SHIP_INTERVAL_SECONDS (pristinum 300). Navigatio
idempotens est: quod iam servatum est omittitur, et custodia base solum semel
cum suus index scriptus est, postremo, ut servata numeratur.
Eadem mandata manu curritur:
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
Ut in novo hospite restituas, primum setum reduce, deinde gradus infra sequere
cum directory petito vice voluminis pgbackup et wal-archive petito vice
pgwal:
bun apps/worker/src/backups/main.ts fetch base-20260924T021500Z /srv/restore
Restituere ad tempus
Hoc post amissionem datarum utere: mala importatio, cursus deletus, migratio
contractus quam solvere opus est. Vivas bases datae repraesentat, ideo eam
primum cum exercitio infra exerce.
Elige tempus metae, in UTC, paulo ante damnum:
2026-09-24 09:30:00+00. Liber custodiae (/admin/audit) plerumque
momentum ostendit.
Omne quod scribit compesce:
docker compose -f docker/compose.yaml stop web content worker scheduler collab
Agrum fractum serva usque ad id cum restitutio probata est:
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/
Novissimam custodiam base veterem quam tempus metae in volumen datae
dispone, et recuperationem destinatam posce:
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'
Recupera: Postgres semel cum constitutionibus recuperationis incipe, ex
superpositione Compose ita ut filetulum normale intactum maneat:
Superpositio totum mandatum repraesentat, ideo ea duo constitutiones repetit
quibus recuperatio pendet: max_connections non minus quam
primarii (alioquin recuperatio cum “insufficient parameter settings” frangitur)
et pg_hba.conf adfixum.
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"
Inspece eam antequam quemquam intromittas: catenam custodiae
(docker compose -f docker/compose.yaml run --rm worker bun tooling/audit-verify/run.ts),
et quod data amissa redierint.
Ad normam redi: docker compose -f docker/compose.yaml up -d. Hic Postgres
cum archivatione aperta iterum incipit, et novum tempus WAL incipit. Statim
custodiam base novam cape.
Nomen projectus quire praefixum cuique volumini est; docker volume ls exacta
nomina monstrat.
Exercitium explorationis constitutum
backup-offsite etiam exercitium omni QUIRE_BACKUP_DRILL_INTERVAL_HOURS
(pristinum 168, hebdomadale) currit, et rursus in proxima currendo post unum
fractum. Novissimam custodiam base extra hospitum et omne segmentum WAL post eam
petit, quodque decryptat (quod probat clavem adhuc eos aperire et nihil mutatum
esse), quodque filetulum cum suo indice comparat, inspicit archivum esse
directory datae Postgres, et inspicit WAL a custodia in posterum nullum hiatus
habere. Commentarium in receptorem ut reports/drill-<time>.json et in librum
servitii scribitur; exercitium fractum filetulum aut primum segmentum deesse
nominat.
Exercitium restitutionis
Custodia quae numquam restituta est non est custodia. Exercitium novissimam
custodiam base completam ante tempus metae captam, plus archivum WAL, in Postgres
ablutorium qui nihil cum vivo communicat restituit, et resultatum probat:
docker/scripts/restore-drill.sh # to ninety minutes agodocker/scripts/restore-drill.sh --target "2026-09-24 09:30:00+00"
Tempus metae est UTC eo ipso forma. Custodiam base veterem quam id et WAL
archivatum ultra id desiderat: in nova institutione, custodiam base cape et
expecta proximum segmentum archivatum (cum scripturis saltem minutum) antequam
tempus metae post custodiam eligas. Exercitium Docker et bash in hospite
desiderat, nihil reliqui.
Quisque gradus exercitium frangit:
Restitutibilitas: agmen ablutorium ad tempus metae reicit et aperitur.
Completudo: numerus ordinum cuiusque tabulae contra vivas bases datae
(tooling/restore-drill). Bases datae vivae post tempus metae processerunt,
ideo tabula differre potest eo maiore quod inter 500 ordines et decimam
partem magnitudinis eius est, utraque via (scripturae eam retardant, deletiones
restitutio plura tenet); partitio post tempus metae creata non est tabula
amissa. Latitudinem concessionis in institutione occupatiore cum
QUIRE_DRILL_MAX_BEHIND et QUIRE_DRILL_MAX_DRIFT_RATIO fac. Tabula deesse
aut evacuata frangit.
Integritas: catena hausti custodiae in copia restituta probatur.
Utilitas: rola applicationis per securitatem linea row legit.
Tempus: ab initio ad viride, contra QUIRE_DRILL_RTO_SECONDS
(pristinum 3600).
Numquam in vivas bases datae aut eorum volumina scribit: volumina custodiae et
WAL solum legenti adfiguntur et agmen ablutorium in fine removetur, sive probatum
sive fractum.
QUIRE_DRILL_REPORT in viam pone ut commentarium JSON scribatur, sive probatum
sive fractum, et id in ordine ex hospite Docker curra:
Id monthly et ante quamque promotionem curra. Exercitium fractum promotionem
prohibet. Semel per quadrimester, fac ut quis qui hunc librum non scripsit
veram restitutionem in tempus in hospite vacuo perficiat, hoc solo documento
usus.
Filetuli
Filetuli locales in volumine files vivunt. Eos cum basibus datae custodi, eodem
tempore, et utrumque una restitue:
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 .
Cum repositio obiectorum, versionem bucket incipe et 35 dierum versionum non
currentium serva; recuperatio in tempus pro filetulis tum ipsius bucket est.