Expand AssetRegister and DataRegister with T0/T4 stack assets. Add ResiliencePolicy, PanicSheet, full-server-loss runbook, and five incident playbooks. Update README with mirror status. Mark T02-T05, T07-T08 done; T01 and T06 in progress.
4 KiB
4 KiB
Restore Runbook: Full Server Loss
Trigger: disk failure, VPS deletion, hardware loss, unrecoverable OS corruption.
RTO target: ≤ 1 day full recovery; ≤ 4–8h for code/content/control plane.
Owner: Bernd
Do not restore into a compromised machine. This runbook assumes hardware
loss, not active breach (see IncidentPlaybooks/ransomware.md for breach).
Prerequisites
- Password-manager copy of age backup keys
- OpenBao unseal material (if restoring railiance01 secrets)
- Nextcloud admin or local backup cache access
- IONOS DNS access
warden signSSH access to new host- This repo cloned (from mirror once T01 complete; until then: any copy)
Phase 1 — Provision clean host
- Provision new Ubuntu server (or recover WSL2 workstation for dev lane only).
- Apply SSH hardening via Ansible (
railiance-infra). - Install tooling:
age,docker,k3s,helm,kubectl,ansible. - Record new host identity in
AssetRegister.yamlafter recovery.
Phase 2 — Secret recovery
- Retrieve OpenBao unseal keys from sealed recovery vault (password manager).
- If railiance01: follow
railiance-platformOpenBao deploy/unseal runbooks. - Retrieve backup upload credentials from OpenBao if re-wiring backup jobs.
- Do not copy plaintext secrets into Git, chat, or State Hub.
Phase 3 — Data restore (by lane)
Dev workstation (bnt-lap001)
- Download latest
db-*.sql.ageandconfig-*.tar.gz.agefrom Nextcloud. age -d -i ~/.config/age/railiance-backup.key -o dump.sql db-*.sql.age- Restore PostgreSQL
custodiandatabase intoinfra-postgres-1. - Decrypt and unpack config tar to
$HOME. - Verify:
bin/railiance preflightexits 0.
Reference: railiance-cluster/docs/backup-restore.md
railiance01 — S1 OS config (optional)
- Decrypt
os-config-*.tar.gz.agefrom/opt/backup/railiance/infra/(if disk survived) or offsite copy when wired. - Restore files or re-apply Ansible playbooks (preferred).
railiance01 — S2 k8s runtime
- If rebuilding k3s: install k3s on clean host.
- Decrypt
helm-values-*.tar.gz.age— redeploy each release with saved values. - Decrypt
kubeconfig-*.yaml.ageif needed for admin access. - k3s
state.dbhot backup: prefer redeploy from Git/Helm over raw DB restore.
Reference: railiance-cluster/tools/cmd/railiance-backup-s2
Gitea (coulombcore)
- If coulombcore lost: provision host, install Gitea via Ansible.
- Restore from latest
gitea dumpor git mirrors of critical repos. - Verify: clone
coulomb/disaster-control, API health.
Forgejo (railiance01)
- If automated backup wired: download latest dump from Nextcloud.
- Run
railiance-infra/tools/forgejo-restore-drill.sh(adapt for production namespace). - Verify:
GET /api/v1/version, org repos visible.
Evidence: TestEvidence/restore-drill-2026-07-04-forgejo.md
Platform databases
Blocked until BackupPickupQueue.md items 3–4 close (platform tool missing).
Phase 4 — Validate services
| Check | Command / endpoint |
|---|---|
| k3s nodes | kubectl get nodes |
| Forgejo health | curl -fsS https://forgejo.coulomb.social/api/v1/version |
| Gitea health | curl -fsS https://gitea.coulomb.social/api/v1/version |
| State Hub | curl -fsS http://127.0.0.1:8000/state/summary |
| Representative app | App-specific smoke (e.g. vergabe health endpoint) |
Phase 5 — DNS cutover
- Confirm all services healthy on new infrastructure.
- Update IONOS A records per
PanicSheet.md§5. - Wait for TTL propagation; verify externally (
dig @8.8.8.8). - Monitor for 24h.
Phase 6 — Evidence report
Write TestEvidence/restore-drill-YYYY-MM-DD-full-server-loss.md:
- Start/end times (RTO measured)
- Backup artifacts used (RPO achieved)
- Systems restored vs redeployed
- Issues and follow-up actions
- Update
AssetRegister.yamlif host identities changed
References
PanicSheet.mdBackupPolicy.mdAssetRegister.yamlRTO-RPO-Matrix.md