From f1044cac00f0509fd896941bbe6fee3c5f2c4e89 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 5 Sep 2026 19:32:00 +0000 Subject: [PATCH] docs(docs): add the Backup & restore page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase-2 documentation restructure — another additive "new page". Backup and restore were split across the deployment guide (how to back up) and the upgrading guide (the restore/rollback steps), so an operator hunting the rollback path had to piece it together. - Add apps/docs/backup-restore.md (Operate, 558 words): what to back up (database + file storage, kept consistent), how (online SQLite snapshot, pg_dump, stop-and-copy, S3), the restore procedure that doubles as the post-upgrade rollback path, the desktop app's data directory, and when. - Trim deployment's "Backups" section to a one-paragraph summary plus a pointer, keeping the ## Backups heading so the deployment#backups anchor (linked from upgrading and the production checklist) still resolves. - Add a "Backup & restore" entry to the "Running your instance" sidebar, next to Upgrading. Retention/cleanup is a separate page in the plan and stays in Storage. No existing page URL or heading anchor changes. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01GKdmqq1BRUPeH5BxSPV5Jj --- apps/docs/.vitepress/config.mts | 1 + apps/docs/backup-restore.md | 68 +++++++++++++++++++++++++++++++++ apps/docs/deployment.md | 26 +------------ 3 files changed, 71 insertions(+), 24 deletions(-) create mode 100644 apps/docs/backup-restore.md diff --git a/apps/docs/.vitepress/config.mts b/apps/docs/.vitepress/config.mts index 37487d4f..0ec80d51 100644 --- a/apps/docs/.vitepress/config.mts +++ b/apps/docs/.vitepress/config.mts @@ -141,6 +141,7 @@ export default defineConfig({ items: [ { text: 'Deployment', link: '/deployment' }, { text: 'Upgrading', link: '/upgrading' }, + { text: 'Backup & restore', link: '/backup-restore' }, { text: 'Configuration reference', link: '/configuration' }, { text: 'Configuration generator', link: '/configuration/generator' }, { text: 'Authentication', link: '/authentication' }, diff --git a/apps/docs/backup-restore.md b/apps/docs/backup-restore.md new file mode 100644 index 00000000..c6c96c65 --- /dev/null +++ b/apps/docs/backup-restore.md @@ -0,0 +1,68 @@ +--- +title: Backup & restore +lang: en-US +--- + +# Backup & restore + +Piwi's migrations are **forward-only** — once a new version has migrated your database, an older version will not run against it correctly. So a backup is not just insurance against disk loss; it is the *only* rollback path. Take one before every version bump. + +## What to back up + +Everything lives in two places — back up both, together: + +1. **The database** — the SQLite file `.data/piwi.db` (the default), or your PostgreSQL database. +2. **File storage** — `.data/storage/` (HTML reports, traces, attachments), unless you keep artifacts in [S3](./storage#s3-compatible-storage), in which case the bucket is your storage backup. + +The two must be consistent with each other: a database row points at a stored trace, so a backup that captures one without the other can dangle. The simplest way to guarantee consistency is to stop the container before copying; the online methods below avoid the downtime. + +## Backing up + +::: code-group + +```bash [SQLite (online, no downtime)] +# Consistent SQLite snapshot without stopping the server, plus the storage dir +sqlite3 .data/piwi.db ".backup '.data/piwi-backup.db'" +tar czf piwi-backup.tar.gz -C .data piwi-backup.db storage +``` + +```bash [PostgreSQL] +pg_dump "$PIWI_DATABASE_URL" > piwi-db.sql +tar czf piwi-storage.tar.gz -C .data storage # skip if artifacts are in S3 +``` + +```powershell [Windows (stop first)] +# Stop the container for a consistent copy, then archive .data +Compress-Archive -Path .data -DestinationPath piwi-backup.zip +``` + +::: + +If artifacts are in S3, lean on the bucket's own durability and versioning rather than copying `.data/storage/`. Keep the database backup and the storage backup from the *same moment* so they agree. + +## Restoring + +Restoring is also how you roll back after an upgrade goes wrong — the rollback path is "restore your backup", never "pull the old tag" against an already-migrated database. + +1. **Stop the container.** +2. **Restore the database and `.data/storage/`** from a backup pair taken at the same time. For SQLite, put `piwi-backup.db` back as `.data/piwi.db` and unpack the storage archive; for PostgreSQL, restore the dump into an empty database (`psql "$PIWI_DATABASE_URL" < piwi-db.sql`). +3. **Start the version the backup was taken on.** A backup from version *N* must be restored under version *N* (or newer, which will migrate it forward) — not an older one. + +Then confirm the running version at **Settings → About**, and that recent runs are present. See [Upgrading](./upgrading) for the full version-change story and the checks that tell you a migration landed. + +## The desktop app + +The [desktop build](./desktop) bundles its own server, and its database and storage live in a per-machine data directory *outside* the app bundle, migrated on first launch exactly as the server does — so the same forward-only rule applies. Back up that data directory before a major version jump; a newer build will migrate it, an older one cannot open it. + +## When to back up + +- **Before every version bump** — this is the one that matters, because it is the only rollback path. +- **On a schedule** matched to how much history you would hate to lose — nightly is plenty for most teams. +- Retention pruning deletes runs permanently; if you want a longer tail than your [retention window](./storage#data-retention) keeps, a periodic backup is where that history lives. + +## Related + +- [Upgrading](./upgrading) — forward-only migrations and verifying an upgrade +- [Deployment](./deployment) — the volume layout and resource sizing +- [Database](./database) — SQLite versus PostgreSQL +- [Storage → Data retention](./storage#data-retention) — what the nightly sweep prunes diff --git a/apps/docs/deployment.md b/apps/docs/deployment.md index c4a6edd8..6436c976 100644 --- a/apps/docs/deployment.md +++ b/apps/docs/deployment.md @@ -405,31 +405,9 @@ When auth is enabled, set `PIWI_SITE_URL` to the public HTTPS URL so email links ## Backups -Everything lives in two places — back both up: +Everything lives in two places — the database (`.data/piwi.db` or your PostgreSQL database) and file storage (`.data/storage/`, unless you use [S3](/storage)). Back up both, together, before every version bump: migrations are forward-only, so a backup is the only rollback path. -1. **The database** — SQLite file `.data/piwi.db` (default) or your PostgreSQL database (`pg_dump`). -2. **File storage** — `.data/storage/` (HTML reports, traces, attachments), unless you use [S3 storage](/storage). - -With the default SQLite + local storage setup, a consistent backup is simply a copy of `.data/` while the container is stopped — or use SQLite's online backup to avoid downtime: - -::: code-group - -```bash [Linux / macOS] -# Online, consistent SQLite backup + storage copy -sqlite3 .data/piwi.db ".backup '.data/piwi-backup.db'" -tar czf piwi-backup.tar.gz -C .data piwi-backup.db storage -``` - -```powershell [Windows (PowerShell)] -# Stop the container first for a consistent copy, then: -Compress-Archive -Path .data -DestinationPath piwi-backup.zip -``` - -::: - -With PostgreSQL: `pg_dump` the database and copy `.data/storage/` (or rely on your S3 bucket's own durability/versioning). - -Take one before every version bump: migrations are forward-only, so a backup is the only rollback path. See [Upgrading](./upgrading). +The full procedure — online SQLite snapshots, `pg_dump`, restoring, and the desktop app's data directory — is on [Backup & restore](./backup-restore). ## Resource requirements