Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,33 @@ docker compose --profile backup run --rm backup sh /verify-backup.sh /backups/po
can afford to drop. The script refuses to run when that URL equals the live backup source.
</Callout>

<h2>Restore drill: what "restore-tested" actually verifies</h2>
<p>
This exact flow was run against a real production backup on a live instance on 2026-07-04
(backup <code>gittensory-20260704T090939Z.dump</code>): the dump was restored into a
throwaway, network-isolated scratch database (a separate container, never the live one),
which the script's own identity check confirmed was distinct from the backup source before
touching anything. The restore completed cleanly and, at the time of this drill, repopulated
all 84 application tables, including the largest operational tables with their full row
counts intact (hundreds of thousands of rows in the biggest tables) — not just an empty
schema. Table and row counts will grow over time; treat them as a point-in-time result, not
an invariant.
</p>
<p>
This proves the backup content and the restore path both work end-to-end against real data.
It deliberately stops short of booting a full app instance against the scratch database and
polling <code>/ready</code>: that endpoint also gates on live Redis, Qdrant, the configured
AI provider, Codex auth, and a real GitHub App key (see{" "}
<Link to="/docs/self-hosting-operations">Operations</Link>'s health endpoints section) —
reproducing all of those for a disposable scratch instance would mean copying real
credentials into new, throwaway infrastructure, which is a bigger risk than the drill is
worth. This drill proves the dump can be restored and its contents inspected at the database
layer — it does not exercise the app's own <code>db</code> readiness probe, migration boot
path, or <code>/ready</code> response. A full disaster-recovery rehearsal still needs to
verify app readiness on the target infrastructure, using the operator's own real
credentials.
</p>

<p>
After scaling, revisit <Link to="/docs/self-hosting-operations">Operations</Link> and{" "}
<Link to="/docs/self-hosting-security">Security</Link> because network and credential
Expand Down
Loading