Backup
Restore
Procedura di restore da backup cifrato
Stato
La procedura di restore e' stata validata su due livelli:
- Test logico in
/tmpil 2026-06-24 sullo snapshot20260624-013111. - Restore test completo su droplet temporaneo il 2026-06-26 sullo snapshot
20260626-040002(dropletobelica-restore-test, Ubuntu 24.04, FRA1).
Il test su droplet ha verificato:
- provisioning di una VPS pulita con Docker, zstd, git, PostgreSQL client;
- copia del binario
obelica-backupe della passphrase dal server produzione; - trasferimento dello snapshot cifrato via
rsyncdal server produzione; - decifratura di tutti gli archivi (config, secrets, app-data Forgejo, dump SQL);
- estrazione e verifica archivi
tar.zsterepos.tar.zst; - verifica
gzip -tsu tutti i dump SQL; - restore dei dump SQL in un container Postgres locale (per evitare di toccare i managed DB di produzione);
- conteggio tabelle e dati ripristinati per tutte le app;
- verifica dei Git bundle tramite
git bundle list-headse clone campione diobelica-docsewash-dog-ferrara; - smoke test end-to-end: clone del repo
obelica-docsdal bundle, build Docker con ildocker-compose.ymlripristinato, avvio container e risposta HTTP 200 suhttp://127.0.0.1:3334/; - cleanup dei dati sensibili e dei container di test.
Nota: durante il restore locale dei dump SQL compaiono errori non fatali
ERROR: role "<nome_utente_db>" does not exist. I dati vengono comunque
ripristinati; in un restore reale su managed PostgreSQL i ruoli esistono gia'
perche' creati da DigitalOcean, mentre in un container Postgres locale vanno
creati prima del pg_restore se si vuole mantenere l'ownership originale.
Materiale richiesto
Da backup:
databases/*.sql.gz.enc
forgejo-app-data.tar.zst.enc
repos.tar.zst.enc
config.tar.zst.enc
secrets.tar.zst.enc
offsite-manifest.txtDa config/secret attuali:
/opt/obelica/infra/forgejo/docker-compose.yml
/opt/obelica/infra/forgejo/.env
/opt/obelica/secrets/apps/forgejo.env
/opt/obelica/secrets/.backup-passphraseDecifratura
Usare il binary Rust:
BIN=/opt/obelica/infra/bin/obelica-backup
$BIN --decrypt databases/forgejo.sql.gz.enc forgejo.sql.gz
$BIN --decrypt forgejo-app-data.tar.zst.enc forgejo-app-data.tar.zst
$BIN --decrypt repos.tar.zst.enc repos.tar.zst
$BIN --decrypt secrets.tar.zst.enc secrets.tar.zst
$BIN --decrypt config.tar.zst.enc config.tar.zstNota: dal 2026-07-03 anche repos.tar.zst e' cifrato (snapshot precedenti lo
hanno in chiaro senza suffisso .enc).
Verifiche rapide:
gzip -t forgejo.sql.gz
zstd -t forgejo-app-data.tar.zst
zstd -t secrets.tar.zst
zstd -t config.tar.zst
tar -I zstd -tf repos.tar.zst | headRestore Forgejo
- Fermare Forgejo.
cd /opt/obelica/infra/forgejo
docker compose down- Salvare una copia dello stato corrente.
mv /opt/obelica/data/forgejo /opt/obelica/data/forgejo.restore-before-YYYYMMDD
mkdir -p /opt/obelica/data/forgejo/app
mkdir -p /opt/obelica/data/forgejo/postgres- Ripristinare app-data.
tar -I zstd -xf forgejo-app-data.tar.zst -C /opt/obelica/data/forgejo- Avviare solo Postgres o l'intero stack controllando i log.
cd /opt/obelica/infra/forgejo
docker compose up -d forgejo-db
docker compose logs --tail=100 forgejo-db- Ripristinare dump SQL.
gunzip -c forgejo.sql.gz | docker exec -i forgejo-db psql -U forgejo -d forgejo- Avviare Forgejo.
docker compose up -d forgejo
docker compose ps- Verificare.
curl -I http://127.0.0.1:3333
docker exec forgejo-db psql -U forgejo -d forgejo -tAc 'select 1;'- Test funzionale.
- login admin;
- lista repository;
- clone;
- push tramite Forgejo, non bare repo;
- verifica token e webhook se presenti.
Restore app
Per ogni app PostgreSQL:
/opt/obelica/infra/tools/obelica-backup \
--decrypt databases/<app>.sql.gz.enc <app>.sql.gz
gunzip -c <app>.sql.gz | psql "<DATABASE_URL>"Restore repository
Estrarre i bundle:
mkdir -p /tmp/obelica-repos-restore
tar -I zstd -xf repos.tar.zst -C /tmp/obelica-repos-restoreVerificare un bundle:
mkdir -p /tmp/bundle-check
git -C /tmp/bundle-check init
git -C /tmp/bundle-check bundle verify /tmp/obelica-repos-restore/repos/obelica-docs.bundleNote
- Non eseguire questa procedura direttamente in produzione senza backup dello stato corrente.
- Testare prima su droplet temporaneo o path isolato.
- In un container Postgres locale creare i ruoli corrispondenti agli utenti DB prima del restore
se si vuole evitare gli errori di
ROLE does not existe mantenere l'ownership originale. - Dopo il restore test, distruggere il droplet temporaneo e rimuovere chiavi/secret di test.