Backup and Restore Guide
BetterStatusPage stores runtime state in SQLite plus uploaded assets. Backups are built into the application so operators do not need to copy a live WAL-mode SQLite database manually.
What a backup contains
A backup archive is named:
bsp-backup-TIMESTAMP.backup
It contains:
- a consistent SQLite snapshot created with
VACUUM INTO, which includes the API tokens (as hashes), setup.json,- uploaded files,
- a versioned manifest,
- SHA-256 checksums.
It does not contain:
.env,JWT_SECRET,VAULT_ENCRYPTION_KEY.
Keep VAULT_ENCRYPTION_KEY separately. Restore requires it explicitly because encrypted vault records cannot be validated or used without the original key.
Create a backup
Build first when using the CLI:
npm run build
npm run backup -- --output ./backups
Docker Compose:
docker compose exec app node apps/api/dist/cli/backup.js
The admin Backups page can also create and download backups.
Verify a backup
CLI:
npm run backup:verify -- --input ./backups/bsp-backup-TIMESTAMP.backup
The admin Backups page can validate an uploaded .backup file before restore.
Restore model
Restore is intentionally offline. Stop the running application before replacing data.
The restore procedure:
- validates the archive structure,
- verifies checksums,
- checks that the supplied
VAULT_ENCRYPTION_KEYmatches the backup, - creates a safety backup of the current state,
- atomically replaces the database and uploads,
- runs migrations,
- rolls back if migration fails.
Restore on bare metal or PM2
pm2 stop bsp
npm run restore -- --input ./backups/bsp-backup-TIMESTAMP.backup --vault-encryption-key YOUR_64_CHARACTER_HEX_KEY
pm2 start bsp
If you do not use PM2, stop the Node.js process with your service manager before running restore.
Restore with Docker Compose
docker compose stop app
docker compose run --rm app node apps/api/dist/cli/restore.js --input /app/backups/bsp-backup-TIMESTAMP.backup --vault-encryption-key YOUR_64_CHARACTER_HEX_KEY
docker compose up -d app
Docker Compose uses a separate bsp_backups volume, so backup archives survive container rebuilds and application data volume changes.
Automatic backups
The admin Backups page can schedule daily or weekly backups. Retention is count-based: after a successful scheduled backup, older automatic archives are removed according to the configured retention count.
Recommended baseline:
- daily backups,
- at least 7 retained archives,
- periodic download to off-host storage,
- restore drill before production launch and after major upgrades.
Restore drill checklist
Before relying on backups in production:
- create a fresh backup,
- copy it to a non-production environment,
- stop the test app,
- restore with the original
VAULT_ENCRYPTION_KEY, - start the test app,
- verify login,
- review Administration → API tokens: a restored backup brings back every token that was revoked after it was taken,
- verify monitors,
- reveal or resolve one test vault secret,
- verify uploads/branding,
- verify
/readyreturns 200.
Common failures
VAULT_ENCRYPTION_KEY does not match
The supplied key is not the key used when the backup was created. Use the original 64-character hex key.
Database is in use or BetterStatusPage is still running
The application is still running. Stop the app first. Restore is not an online operation.
Unsupported backup format
The file is not a BetterStatusPage .backup archive or was created by an incompatible future version.
Checksum or integrity failure
Treat the backup as corrupted. Use another archive and investigate storage/download corruption.