Every MSP documentation platform holds the same nightmare scenario: the host disappears — hardware failure, ransomware, a bad docker compose down -v at 2am — and with it goes every client credential, network diagram, and asset record you have. If your only copy lived on that one box, you don’t have a documentation platform anymore. You have an incident.
Weavestream is self-hosted, which means backup and restore isn’t someone else’s SLA — it’s yours to configure. The platform makes that straightforward with in-app scheduled exports, checksummed manifests, and a documented restore path, instead of leaving you to script pg_dump cron jobs from scratch.
Scheduled Backups, Configured in the Admin UI
Any SUPER_ADMIN, or an operator with the BACKUP_MANAGE capability, can set up scheduled backups under Admin → Backups — no shell access required. Each schedule runs on a cron expression (or a preset like “daily at 3am”), in a timezone you choose, and produces a pg_dump --format=custom export alongside a JSON manifest.
Retention is configurable per schedule:
- Keep last — retain the N most recent successful runs, regardless of date bucket (default: 3)
- Daily — one run per calendar day
- Weekly — one run per ISO week
- Monthly — one run per calendar month
You can layer these, and you can add notification emails so a failed run doesn’t go unnoticed. Click Run now once to confirm the schedule actually works before you trust it.
Every Dump Ships With a Manifest
This is the part most homegrown pg_dump cron jobs skip. Every scheduled backup produces two files:
weavestream-postgres-<timestamp>.dump
weavestream-postgres-<timestamp>.manifest.json
The manifest records the dump filename, a SHA-256 checksum, the Weavestream version, the Prisma migration hash, the database hostname, and the active password-encryption key ID at the time of the backup. That last field matters more than it sounds: if you rotate your PASSWORD_ENCRYPTION_KEY at some point, the manifest tells you exactly which key a given dump needs to decrypt correctly on restore.
Runs are also protected by a Postgres advisory lock — if a second run starts while one is already in flight, it fails cleanly with error = 'concurrent' instead of corrupting the export.
What’s in the Dump, and What Isn’t
The Postgres export contains every Weavestream table — companies, assets, articles, password records (encrypted), audit history, all of it. It does not contain two things you also need for a full restore:
$DATA_DIR/files— uploaded attachments, logos, thumbnails, and generated export PDFs live on the filesystem, not in the database..envsecrets —PASSWORD_ENCRYPTION_KEY,MFA_ENCRYPTION_KEY,JWT_SIGNING_KEY, and related keys aren’t in the dump at all. Without the original keys, encrypted vault data in a restored database can’t be decrypted, full stop.
A complete backup is the dump, the files directory, and .env — treated as one set, stored together, never separated.
Getting Backups Off the Host
An in-app schedule protects you from database corruption or a bad migration. It does not protect you from losing the host entirely, because by default the dumps land back on the same disk ($DATA_DIR/backup). Weavestream doesn’t encrypt the dump itself, so the guidance is explicit: replicate it off-host through something that does — restic, borg, or rclone with crypt support are all mentioned directly in the docs as reasonable choices.
A minimal off-host set to sync nightly:
$DATA_DIR/backup/ # scheduled dumps + manifests
$DATA_DIR/files/ # uploads and attachments
.env # encryption and signing keys
Because the in-app dumps are bit-for-bit identical to a manual pg_dump --format=custom run, they deduplicate well across nightly snapshots in tools like restic — you’re not paying for a full copy every night just because the schedule ran.
Restoring on a Fresh Host
The documented restore path assumes the worst case: the original Docker host is gone, and you’re starting from a .dump file, a files backup, and the original .env. In broad strokes:
- Stand up a new host, restore
.env, and lay down thefilesbackup under$DATA_DIR. - Start Postgres alone and wait for it to report healthy.
- Run
pg_restore --clean --if-existsagainst the dump. - Bring up the full stack — the API container runs pending migrations automatically on boot.
- Verify the restore actually worked.
That last step isn’t optional. Weavestream’s own checklist has you open a saved password and confirm it decrypts (proves .env matched), open an uploaded attachment (proves files restored), and confirm Admin → Backups history is intact — before you call the restore done.
Why This Matters for MSP Compliance, Not Just Uptime
A documentation platform holding every client credential, network diagram, and admin contact you manage is exactly the kind of system client contracts and compliance frameworks expect you to have a real, tested disaster recovery plan for — not a hope that the vendor’s SaaS backups are fine. When you’re self-hosting, “we have backups” only counts if you can point to a schedule that actually ran, a checksum that actually validates, and a restore you’ve actually tested on a clean host.
That’s the difference between a backup feature and a backup plan. Weavestream gives you the former out of the box — the schedule, the manifest, the retention policy, the documented restore steps. Turning it into the latter is a matter of running it, syncing it off-host, and testing the restore once so you’re not finding out whether it works during the actual incident.
Getting Started
If you’re already running Weavestream, go to Admin → Backups, create a schedule, and click Run now to confirm it. Then get the resulting $DATA_DIR/backup and $DATA_DIR/files directories — plus your .env — onto encrypted off-host storage on a recurring basis.
New to Weavestream? The quickstart guide gets the stack running with Docker Compose, and the full Backup & Restore guide walks through scheduling, off-host replication, and restore on a fresh host step by step.