Restore Drill Playbook: Prove Backups Before You Trust Them
Published 2026-07-20 · Updated 2026-08-24 · 18 min read · By Ben Liu
A practical restore drill: what to back up, how to restore to scratch, offsite S3-compatible copies, and a calendar you will actually keep.
Backups without restores are theater
A green cron job is not evidence. Evidence is: wipe a scratch host, restore from last night's artifact, and open the real app until you find last week's photo, vault entry, or git commit.
What must be in the backup set
For each compose project list: bind mounts / named volumes that hold durable data, database dump method (or volume that contains the DB files), `.env` / secret files, and the compose YAML itself. Thumbnails and caches are optional; originals and DB state are not.
| Layer | Include | Skip |
|---|---|---|
| App config | compose.yml, .env, STACK.md | Host OS packages (reinstallable) |
| Databases | Logical dump or consistent volume snapshot | Ephemeral Redis unless it is the source of truth |
| Object / media | Originals + metadata DB together | Regenerable derivatives |
| Secrets | Encrypted export or sealed offline copy | Plaintext in the same bucket as the dump |
Drill procedure (90 minutes or less)
- Pick one critical service (photos, vault, or forge).
- Snapshot or note the live health URL and a unique recent object (album date, password item name, commit hash).
- Provision a scratch project on another path or host — never restore onto production volumes first.
- Restore dumps + volumes from the artifact you claim is good.
- Bring the stack up with pinned tags from STACK.md.
- Prove the unique object exists and auth still works.
- Log date, minutes elapsed, artifact ID, and who ran the drill.
# pattern only — adjust paths
mkdir -p /tmp/restore-drill && cd /tmp/restore-drill
# restore volume tarball + .env + compose.yml here
docker compose up -d
# open the app; search for a known object; then tear down
docker compose downOffsite and S3-compatible storage
Local snapshots die with the rack. Keep an encrypted copy off-site (restic/Borg/rclone to S3-compatible). Encrypt before upload. Store the key where the bucket alone cannot decrypt the archive.
Test download + decrypt on a machine that is not the production host. A bucket listing is not a restore.
Cadence
Quarterly minimum for household stacks; monthly for anything that holds identity or irreplaceable media. After major upgrades, run a mini-drill before you delete the previous artifact.
Calendar the next drill when you finish this one. Untimed "someday" restores never happen.
Failure modes to expect
Wrong volume restored; DB newer than media; `.env` missing; image tag floated; ACL blocked download; restore succeeded but SSO IdP is elsewhere. Write each failure into the drill log so the next run is faster.
Lab notes pending — replace with measured values before publishing claims.
[Add real environment data here]
Host / OS:
Backup tool + version:
Offsite target:
Last successful drill date:
Minutes to verify:
Artifact ID:Related reading
See Docker Compose hardening, Updating without fear, Family handoff documentation, and What is self-hosting.
Explore more
Related guides
- Reverse Proxy and Automatic TLS for Homelabs
One ops guide for reverse proxy + ACME: what a proxy solves, Caddy/Traefik/Nginx fit, certificate renewal, Docker wiring, failure modes, and troubleshooting — without three overlapping primers.
- Family Handoff Docs: Keep the Homelab Alive Without You
Write a one-hour handoff pack so a partner or friend can restart services, restore from backup, and contact you with useful facts.
- Family Photo Library: Ingest, Compare, Backup, Restore
Run a household photo library without losing the archive — Immich vs PhotoPrism vs Nextcloud Photos, ingest/dedup, sharing, permissions, backup, and restore drills.