D1 Backup and Restore Runbook
This runbook covers the local parts of RFC-007 Phase 5.
Files
- Backup script:
scripts/d1-backup.sh - Backup workflow:
.github/workflows/d1-backup.yml - Default output path:
backups/d1/*.sql
Automated Backups (GitHub Actions)
The backup workflow runs automatically:
- Scheduled: Daily at 00:00 UTC via
.github/workflows/d1-backup.yml - Manual: Trigger via GitHub Actions workflow_dispatch
Setup
-
Add secrets to GitHub repository:
CLOUDFLARE_API_TOKEN: Cloudflare API token with D1 and R2 write accessCLOUDFLARE_ACCOUNT_ID: Cloudflare account IDR2_BACKUP_BUCKET: R2 bucket name (optional, for cloud storage)
-
The workflow will:
- Export the remote D1 database
- Upload to R2 (if configured)
- Keep last 7 backups locally in repository
Manual Backup procedure
- Local backup:
./scripts/d1-backup.sh local
- Remote backup:
./scripts/d1-backup.sh remote
- Remote backup + upload to R2:
R2_BACKUP_BUCKET=your-backup-bucket R2_OBJECT_PREFIX=photobooth/d1 ./scripts/d1-backup.sh remote
Restore procedure
- Identify backup file to restore.
- Apply to local D1 for verification:
npx wrangler d1 execute photobooth-db --local --file backups/d1/<backup-file>.sql
- Validate critical tables:
npx wrangler d1 execute photobooth-db --local --command "SELECT COUNT(*) AS payments FROM payments;"
npx wrangler d1 execute photobooth-db --local --command "SELECT COUNT(*) AS licenses FROM licenses;"
- After validation, execute restore in remote environment during approved maintenance window:
npx wrangler d1 execute photobooth-db --remote --file backups/d1/<backup-file>.sql
Operational checks
- Confirm export file is non-empty.
- Confirm restore SQL exits successfully.
- Confirm row counts and a sample payment lookup after restore.
- Record backup timestamp and checksum in the incident/change log.