---
title: "Backup, irkupru puntwal u d-drill tar-restore"
description: "Agħmel backup ta' Quire, irrestawraha għal punt fiż-żmien, u ppruvaha bid-drill tar-restore."
image: "https://docs.quirelms.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.quirelms.com/mt/llms.txt
> Use this file to discover all available pages before exploring further.

# Backup, irkupru puntwal u d-drill tar-restore

<span id="backup-point-in-time-recovery-and-the-restore-drill"></span>

Id-disinn jinsab f'`docs/architecture/23-ops.md` sezzjoni 8. Dan huwa r-runbook
għall-prodott Docker Compose. Jinkiteb biex jiġi segwit minn xi ħadd li
ma kitbux; jekk pass mhuwiex ċar, dak huwa difett f'dan id-dokument.

## X'inhu protett, u kif <!--quire:what-is-protected-and-how-->

| Asset | How | Where |
| --- | --- | --- |
| Id-database | WAL arkivjat kontinwament, kull 60 sekonda l-aktar, mill-ewwel boot | Volum `pgwal` |
| Id-database | Backups bażi b'`pg_basebackup`, kuljum default (`backup-scheduler`) | Volum `pgbackup` |
| Id-database | Kopji encrypted tal-backups bażi u l-WAL, kull ħames minuti (`backup-offsite`) | Maħżen separat li ssemmi int |
| Files | Il-volum `files`. Ikkopjah bl-għodda tal-backup tal-host tiegħek, jew uża ħażna ta' oġġetti verżjonata | Volum `files` |
| Secrets | `docker/.env`, fuq kollox `QUIRE_MASTER_KEY` (u kwalunkwe `QUIRE_MASTER_KEY_RETIRED` li għadu jintuża), `QUIRE_BACKUP_ENCRYPTION_KEY`, u `docker/secrets/audit-signing-key.pem` | Żomm kopja barra dan il-host |
| Search indexes, caches, renditions | Mhux backed up; mibnija mill-ġdid | |

Miri: punt ta' rkupru fi żmien 60 sekonda mill-ħsara, u restore
fi żmien 60 minuta għal database ta' 500 GB.

Żewġ żbalji huma komuni. Database rrestawrata **mingħajr il-fajls tagħha** tagħmel
paġni miksura. Database rrestawrata **mingħajr `QUIRE_MASTER_KEY`** ma tistax
tiddekripta l-kredenzjali SSO, webhook u integrazzjoni li żżomm; sakemm rotazzjoni ta' ċavetta master
tintemm b'xejn mhux solvut ([key-rotation.md](/mt/ops/key-rotation/)),
dan jinkludi ċ-ċwievet irtirati. It-tnejn huma parti mill-backup.

## Teħid ta' backups <!--quire:taking-backups-->

Backup bażi tal-cluster kollu:

```sh
docker compose -f docker/compose.yaml --profile backup run --rm backup
```

Iżomm l-aktar backups bażi ġodda ta' `QUIRE_BACKUP_KEEP` (default 5) u jneħħi
WAL li l-eqdem waħda ma teħtieġx aktar, biex l-arkivju ma jistax jikber bla limitu.
Skedaha kuljum b'cron jew timer systemd fuq il-host:

```cron
15 2 * * * cd /srv/quire && docker compose -f docker/compose.yaml --profile backup run --rm backup >> /var/log/quire-backup.log 2>&1
```

Jew ħalli l-istack tiskedaha: il-profil `backup` imexxi `backup-scheduler`,
li jieħu backup bażi kull `QUIRE_BACKUP_INTERVAL_HOURS` (default 24),
u `backup-offsite`, deskritt wara.

```sh
docker compose -f docker/compose.yaml --profile backup up -d
```

## Kopji encrypted barra l-host <!--quire:encrypted-off-host-copies-->

Iż-żewġ volumi jgħixu fuq l-istess host mad-database, u backup fuq il-
magna li falliet mhuwiex backup. `backup-offsite` jikkopja kull backup bażi
u kull segment WAL arkivjat lil maħżen separat permezz tal-port tal-ħażna,
encrypted, u jżommhom hemmhekk taħt retention:

- **Encryption.** AES-256-GCM b'`QUIRE_BACKUP_ENCRYPTION_KEY` (jew il-fajl
  imsemmi minn `QUIRE_BACKUP_ENCRYPTION_KEY_FILE`): 32 bytes, minn
  `openssl rand -hex 32`. Kull fajl għandu n-nonce tiegħu u tag tal-awtentikazzjoni,
  biex kopja ma tinqarax mingħajr iċ-ċavetta u kwalunkwe bidla fiha tiġi
  skoperta. Żomm iċ-ċavetta ma' `QUIRE_MASTER_KEY`, 'il bogħod minn dan il-host u 'l bogħod
  mill-maħżen tal-backup. Mingħajr iċ-ċavetta m'hemm l-ebda restore.
- **Fejn.** `QUIRE_BACKUP_STORAGE_DRIVER` huwa `s3`, `azure` jew `local` (disk
  remot mounted f'`QUIRE_BACKUP_STORAGE_ROOT`). Is-settings huma dawk tal-ħażna tal-fajls
  b'prefiss `QUIRE_BACKUP_`: `QUIRE_BACKUP_S3_ENDPOINT`,
  `QUIRE_BACKUP_S3_BUCKET`, `QUIRE_BACKUP_S3_ACCESS_KEY_ID`, eċċ. Uża
  bucket differenti u, idealment, kont differenti mill-fajls, b'
  kredenzjali li jistgħu jiktbu iżda ma jħassrux jekk il-fornitur jippermetti.
- **Retention.** L-aktar backups bażi ġodda ta' `QUIRE_BACKUP_OFFSITE_KEEP` (default
  `QUIRE_BACKUP_KEEP`, inkella 7) u l-WAL li l-eqdem minnhom teħtieġ; settijiet u segmenti eqdem
  jitħassru mill-maħżen.
- **Meta.** Kull `QUIRE_BACKUP_SHIP_INTERVAL_SECONDS` (default 300). Il-bagħt
  huwa idempotenti: dak li diġà huwa maħżen jinqabeż, u backup bażi jgħodd
  bħala maħżen biss ladarba l-manifest tiegħu jinkiteb, l-aħħar.

L-istess kmand jaħdem bl-idejn:

```sh
docker compose -f docker/compose.yaml run --rm backup-offsite bun apps/worker/src/backups/main.ts ship
docker compose -f docker/compose.yaml run --rm backup-offsite bun apps/worker/src/backups/main.ts verify
```

Biex tirrestawra fuq host ġdid, ġib sett lura l-ewwel, imbagħad segwi l-passi hawn taħt
bid-directory miġjuba minflok il-volum `pgbackup` u l-
`wal-archive` miġjub minflok `pgwal`:

```sh
bun apps/worker/src/backups/main.ts fetch base-20260924T021500Z /srv/restore
```

## Restore għal punt fiż-żmien <!--quire:restoring-to-a-point-in-time-->

Uża dan wara telf ta' data: importazzjoni ħażina, kors imħassar, migrazzjoni
contract li għandek bżonn tħassar. Tissostitwixxi d-database live, għalhekk ipprattikaha
bid-drill hawn taħt l-ewwel.

1. **Agħżel il-ħin fil-mira**, f'UTC, ftit qabel il-ħsara:
   `2026-09-24 09:30:00+00`. Il-log tal-verifika (`/admin/audit`) normalment juri l-
   mument.
2. **Waqqaf kull ma jikteb**:
   `docker compose -f docker/compose.yaml stop web content worker scheduler collab`
3. **Żomm il-cluster imħassar** sakemm ir-restore jiġi vverifikat:
   ```sh
   docker compose -f docker/compose.yaml stop postgres
   docker run --rm -v quire_postgres18-data:/from -v quire_postgres-damaged:/to alpine cp -a /from/. /to/
   ```
4. **Iftaħ l-aktar backup bażi ġdid eqdem mill-mira** fil-volum tad-data,
   u itlob irkupru mmirat:
   ```sh
   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'
   ```
5. **Irkupra**: ibda Postgres darba bis-settings tal-irkupru, minn
   override ta' Compose biex il-fajl normali ma jintmessx:
   ```yaml
   # docker/compose.recover.yaml
   services:
     postgres:
       command: [postgres, -c, "restore_command=cp /var/lib/postgresql/wal-archive/%f %p",
                 -c, "recovery_target_time=2026-09-24 09:30:00+00",
                 -c, recovery_target_action=promote, -c, archive_mode=off,
                 -c, max_connections=200, -c, hba_file=/etc/postgresql/pg_hba.conf]
   ```
   L-override tissostitwixxi l-kmand kollu, għalhekk tirrepeti ż-żewġ settings
   li l-irkupru jiddependi fuqhom: `max_connections` mhux inqas mill-primarja
   (inkella l-irkupru jabbanduna b'"insufficient parameter settings") u
   il-`pg_hba.conf` mounted.
   ```sh
   docker compose -f docker/compose.yaml -f docker/compose.recover.yaml up -d postgres
   docker compose -f docker/compose.yaml logs -f postgres   # wait for "database system is ready"
   ```
6. **Iċċekkjaha** qabel ma tħalli lil ħadd jidħol: il-katina tal-verifika
   (`docker compose -f docker/compose.yaml run --rm worker bun tooling/audit-verify/run.ts`),
   u li d-data mitlufa reġgħet lura.
7. **Erġa' għan-normal**: `docker compose -f docker/compose.yaml up -d`. Dan
   jerġa' jibda Postgres bl-arkivjar mixgħul, u timeline WAL ġdida tibda. Ħu
   backup bażi frisk minnufih.

L-isem tal-proġett `quire` jipprefigġi kull volum; `docker volume ls` juri l-
ismijiet eżatti.

## Id-drill tal-verifika skedata <!--quire:the-scheduled-verification-drill-->

`backup-offsite` imexxi wkoll drill kull `QUIRE_BACKUP_DRILL_INTERVAL_HOURS`
(default 168, kull ġimgħa), u mill-ġdid fil-pass li jmiss wara li wieħed ifalli. Huwa jġib
l-aktar backup bażi ġdid barra l-host u kull segment WAL warajh, jiddekripta kull wieħed
(li jipprova li ċ-ċavetta xorta tiftaħhom u xejn ma ġie mibdul), iqabbel kull
fajl mal-manifest tiegħu, jiċċekkja li l-arkivju huwa directory tad-data ta' Postgres, u
jiċċekkja li l-WAL mill-backup 'il quddiem m'għandu l-ebda vojt. Ir-rapport jinkiteb fil-
maħżen bħala `reports/drill-<time>.json` u fil-log tas-servizz; drill fallut isemmi
il-fajl jew l-ewwel segment nieqes.

## Id-drill tar-restore <!--quire:the-restore-drill-->

Backup li qatt ma ġie rrestawrat mhuwiex backup. Id-drill jirrestawra l-
aktar backup bażi komplut ġdid meħud qabel il-mira, flimkien mal-arkivju WAL,
f'Postgres scratch li ma jaqsam xejn mal-live, u jipprova r-
riżultat:

```sh
docker/scripts/restore-drill.sh                                  # to ninety minutes ago
docker/scripts/restore-drill.sh --target "2026-09-24 09:30:00+00"
```

Il-mira hija UTC f'dik il-forma eżatta. Jeħtieġ backup bażi eqdem minnha
u WAL arkivjat lil hinn minnha: fuq installazzjoni ġdida, ħu backup bażi u stenna għas-
segment arkivjat li jmiss (l-aktar minuta bi kitbiet) qabel ma tagħżel
mira wara l-backup. Id-drill jeħtieġ Docker u bash fuq il-host, xejn
ieħor.

Kull pass ifalli d-drill:

1. **Irkuprabbiltà**: il-cluster scratch jerġa' jdoqq sal-mira u jiftaħ.
2. **Kompletezza**: l-għadd tar-ringieli ta' kull tabella kontra d-database live
   (`tooling/restore-drill`). Id-database live mexgħet 'il quddiem mill-mira,
   għalhekk tabella tista' tvarja bl-akbar ta' 500 ringiela u għaxra tad-daqs tagħha, fi
   kull direzzjoni (kitbiet jagħmluha lura, tħassir jagħmel ir-restore jżomm aktar);
   partizzjoni maħluqa wara l-mira mhijiex tabella mitlufa. Wessa' l-
   allowance fuq installazzjoni aktar traffikuża b'`QUIRE_DRILL_MAX_BEHIND` u
   `QUIRE_DRILL_MAX_DRIFT_RATIO`. Tabella nieqsa jew vojta tfalli.
3. **Integrità**: il-katina hash tal-verifika tivverifika fuq il-kopja rrestawrata.
4. **Użabbiltà**: ir-rwol tal-applikazzjoni jaqra permezz ta' sigurtà fil-livell tar-ringieli.
5. **Ħin**: mill-bidu għal aħdar, kontra `QUIRE_DRILL_RTO_SECONDS`
   (default 3600).

Qatt ma jikteb fid-database live jew fil-volumi tagħha: il-backup u l-WAL
volumi huma mounted qari biss u l-cluster scratch jitneħħa fl-aħħar,
jgħaddi jew ifalli.

Issettja `QUIRE_DRILL_REPORT` għal mogħdija biex rapport JSON jinkiteb, jgħaddi jew
ifalli, u ħaddmu fuq skeda mill-host Docker:

```cron
30 3 1 * * cd /srv/quire && QUIRE_DRILL_REPORT=/var/log/quire-drill.json docker/scripts/restore-drill.sh >> /var/log/quire-drill.log 2>&1
```

Ħaddmu kull xahar u qabel kull aġġornament. Drill fallut jimblokka l-aġġornament.
Darba kull tliet xhur, ħalli lil xi ħadd li ma kitebx dan ir-runbook iwettaq restore
puntwal reali fuq host żejjed, bl-użu ta' dan id-dokument biss.

## Fajls <!--quire:files-->

Fajls lokali jgħixu fil-volum `files`. Agħmel backup tagħhom mad-database, fl-
istess ħin, u rrestawra t-tnejn flimkien:

```sh
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 .
```

B'ħażna ta' oġġetti, ixgħel il-verżjonar tal-bucket u żomm 35 jum ta'
verżjonijiet mhux attwali; irkupru puntwal għall-fajls imbagħad huwa dak tal-bucket
stess.

Source: https://docs.quirelms.com/mt/ops/backup-restore/index.mdx
