Recovery drill verification for PostgreSQL backups.
RestoreLab answers one question:
Can I actually restore this archive right now, in isolation, without touching production?
It is not a backup tool. It is a verification layer on top of Restic that restores a PostgreSQL archive inside a hardened, disposable Docker container, runs your SQL checks against it, and prints a report showing exactly what was and was not tested.
A backup job reporting "success" only proves the job ran. It does not prove the archive is restorable, and it does not prove the database that comes out of it is structurally correct. The gap between "the backup script exited 0" and "I can actually recover this service" is where real incidents happen — and it usually only gets discovered during an actual outage, when it's too late to do anything but apologize.
RestoreLab closes that gap by giving you a way to prove restorability on a schedule, in an isolated sandbox, without ever touching your production database or host.
flowchart LR
A[("Restic\nrepository")] -->|restore snapshot| B["PostgreSQL\ncustom-format dump"]
B --> C
subgraph C["Hardened disposable Docker sandbox"]
direction LR
D["pg_restore"] --> E["SQL checks\n(your contract)"]
end
E --> F["JSON + HTML\nreport"]
C -.->|always, via defer| G["Cleanup\n(container + volumes removed)"]
style C fill:#0d1117,stroke:#58a6ff,color:#c9d1d9
style G fill:#161b22,stroke:#8b949e,color:#8b949e
The sandbox has no published ports, no Docker socket mount, and never touches your production database. See Security properties for the full list of hardening measures.
| Approach | Archive exists | Archive not corrupted | Database actually restores | Runs isolated from production |
|---|---|---|---|---|
| Backup job reported success | Yes | No | No | — |
restic check |
Yes | Yes | No | — |
pg_restore --list |
Yes | Yes | No | — |
| Manual restore drill by hand | Yes | Yes | Yes | Usually not (spare or prod-adjacent box) |
| RestoreLab | Yes | Yes | Yes | Yes — hardened, disposable container |
Supported: Restic repositories / PostgreSQL (custom-format dumps) / Docker Engine / CLI with JSON + HTML reports.
Not supported in v0.1.0: Borg, PBS, Duplicati / MySQL, MariaDB, SQLite / Kubernetes, Podman / Web UI, scheduler, alerts.
Anything not in the supported list is deliberately deferred to ROADMAP.md and will not enter v0.1.0.
Install directly (requires Go 1.22+):
go install github.com/techdev-lab/restorelab/cmd/restorelab@latestOr build from source:
git clone https://github.com/techdev-lab/restorelab
cd restorelab
go build -o restorelab ./cmd/restorelabOn Debian/Ubuntu, the Docker SDK requires CGO. See docs/BUILD_REQUIREMENTS.md.
Validate a contract:
export RESTIC_REPOSITORY=/path/to/restic-repo
export RESTIC_PASSWORD_FILE=/path/to/password-file
export TEST_DB_PASSWORD=your-sandbox-db-password
./restorelab validate examples/real-world/immich-real-test.yamlRun a drill:
./restorelab run examples/real-world/immich-real-test.yaml \
--json=report.json --html=report.html- Docker Engine 26.0.0+ (fixes CVE-2024-29018)
- Restic 0.14.0+ (0.17.0+ recommended for size metadata)
- Go 1.22+ if building from source
- PostgreSQL image pinned by digest
See docs/REAL-WORLD-VALIDATION.md for findings from running RestoreLab against production backup archives, including a case where it surfaced that a service's data directory contained no persistent database at all — a gap that would only have been discovered during an actual recovery attempt.
cap_drop: ALLno-new-privileges- Read-only root filesystem
- No published ports
- No privileged mode
- No Docker socket mount
- Internal network only
- Artifact bind-mounted read-only
- Memory / PIDs / shm bounded
- Cleanup via
defer, guaranteed on success, failure, or interrupt
See SECURITY.md for the full threat model.
0 success (overall PASS or WARNING)
1 failure (contract invalid, drill failed, runtime error)
2 usage error
- v0.2.0: MariaDB support
- v0.3.0: Borg provider
- v0.4.0: Proxmox Backup Server
- v1.0.0: Optional web UI, scheduling, alerts
See ROADMAP.md for details.
Issues and pull requests are welcome. See CONTRIBUTING.md for guidelines.
MIT. See LICENSE.
