Backup & Restore Guide
This guide explains how to protect a Weavestream deployment and restore it after a host failure.
Weavestream's persistent data lives in three places:
The scheduled backup dump is not encrypted by Weavestream. Store $DATA_DIR/backup on encrypted storage or replicate it with an encrypted tool such as restic, borg, or rclone crypt. Back up .env separately in a secrets vault.
1. Confirm Your Data Directory
By default, compose.yml stores data in ./data next to the compose file. If you set DATA_DIR in .env, use that path instead.
cd /opt/weavestream
grep '^DATA_DIR=' .env || echo "DATA_DIR=./data"
For the rest of this guide:
COMPOSE_DIR=/opt/weavestream
DATA_DIR=$COMPOSE_DIR/data
If your .env uses a custom DATA_DIR, replace the value above.
2. Configure Scheduled Database Exports
- Sign in as a
SUPER_ADMINor a user withBACKUP_MANAGE. - Go to Admin → Backups.
- Click New schedule.
- Choose a preset or enter a five-field cron expression.
- Set the timezone, for example
Etc/UTCorAmerica/New_York. - Set retention:
- Keep last keeps the N most-recent successful runs regardless of date bucket. Default:
3. - Daily keeps one run per distinct day.
- Weekly keeps one run per ISO week.
- Monthly keeps one run per calendar month.
- Keep last keeps the N most-recent successful runs regardless of date bucket. Default:
- Optional: add notification email addresses.
- Save the schedule.
Click Run now once and wait for a successful run. A successful run creates:
$DATA_DIR/backup/weavestream-postgres-<timestamp>.dump
$DATA_DIR/backup/weavestream-postgres-<timestamp>.manifest.json
The manifest includes the dump filename, SHA-256 checksum, Weavestream version, Prisma migration hash, database hostname, and active password-encryption key id.
3. Back Up Files and Dumps Off-Host
The in-app backup only exports PostgreSQL. You must also copy uploaded files.
Minimum off-host backup set:
$DATA_DIR/backup/
$DATA_DIR/files/
.env
Recommended nightly sync:
#!/bin/bash
set -euo pipefail
COMPOSE_DIR=/opt/weavestream
DATA_DIR="$COMPOSE_DIR/data"
DEST=/mnt/backups/weavestream
DATE=$(date +%F)
mkdir -p "$DEST/postgres-dumps" "$DEST/files-$DATE" "$DEST/secrets"
# Database dumps produced by Admin -> Backups.
rsync -a "$DATA_DIR/backup/" "$DEST/postgres-dumps/"
# Uploaded files and generated file artifacts.
rsync -a "$DATA_DIR/files/" "$DEST/files-$DATE/"
# Secrets required to decrypt vaulted data after restore.
cp "$COMPOSE_DIR/.env" "$DEST/secrets/.env"
# Example file snapshot rotation. The database dumps are pruned by
# Weavestream retention, so this only rotates file snapshots.
find "$DEST" -maxdepth 1 -type d -name 'files-*' -mtime +30 -exec rm -rf {} +
For production, run the script from cron or a systemd timer and replicate DEST to a different machine, NAS, or encrypted object storage.
Example with restic:
restic -r s3:https://s3.amazonaws.com/example-weavestream-backups backup \
"$DATA_DIR/backup" \
"$DATA_DIR/files" \
"$COMPOSE_DIR/.env"
4. Optional Manual Database Dump
You can also create a one-off logical dump from the Docker host:
cd /opt/weavestream
docker compose exec -T postgres \
pg_dump -U "$POSTGRES_USER" --format=custom --no-owner --no-acl "$POSTGRES_DB" \
> "weavestream-postgres-manual-$(date -u +%Y-%m-%dT%H-%M-%SZ).dump"
This is useful before upgrades or maintenance. It does not replace $DATA_DIR/files or .env.
5. Restore on a New Docker Host
Use this when the original Docker host is gone and you have:
- A Weavestream
.dumpfile from$DATA_DIR/backup. - A matching
$DATA_DIR/filesbackup. - The original
.env.
Prepare the New Host
mkdir -p /opt/weavestream
cd /opt/weavestream
curl -O https://raw.githubusercontent.com/Weavestream/Weavestream/main/compose.yml
cp /backup/weavestream/secrets/.env .env
mkdir -p data
rsync -a /backup/weavestream/files-2026-05-01/ data/files/
If your original .env set DATA_DIR, recreate that directory and restore files there instead.
Start PostgreSQL Only
docker compose up -d postgres
docker compose ps postgres
Wait until the container is healthy.
Restore the Database Dump
Replace the dump path with the file you want to restore:
docker compose exec -T postgres sh -lc \
'pg_restore --clean --if-exists --no-owner --no-acl \
-U "$POSTGRES_USER" -d "$POSTGRES_DB"' \
< /backup/weavestream/postgres-dumps/weavestream-postgres-2026-05-01T03-00-00Z.dump
If the database already contains partial data and the restore fails, recreate it and retry:
docker compose exec -T postgres sh -lc \
'dropdb -U "$POSTGRES_USER" --if-exists "$POSTGRES_DB" &&
createdb -U "$POSTGRES_USER" "$POSTGRES_DB"'
Then run the pg_restore command again.
Start the Full Stack
docker compose up -d
docker compose ps
The api container runs prisma migrate deploy on boot. If the restored dump already includes all migrations, this is a no-op.
6. Restore Uploaded Files Later
If you restored the database first and need to restore files afterward:
cd /opt/weavestream
docker compose stop api worker
rsync -a /backup/weavestream/files-2026-05-01/ data/files/
docker compose start api worker
7. Verify the Restore
After the stack starts:
- Sign in with an existing admin account.
- Open a saved password and confirm it decrypts. This proves the restored
.envhas the correctPASSWORD_ENCRYPTION_KEY. - Open an uploaded image or attachment. This proves
$DATA_DIR/filesis restored. - Go to Admin → Backups and confirm history is visible.
- Click Run now and confirm a new dump is written to
$DATA_DIR/backup.
8. Troubleshooting
pg_restore: error: input file appears to be a text format dump
The restore command above expects Weavestream's in-app custom-format dump. If you have a .sql or .sql.gz dump, restore it with psql instead:
gunzip -c backup.sql.gz | docker compose exec -T postgres \
psql -U "$POSTGRES_USER" "$POSTGRES_DB"
Passwords or Secrets Do Not Decrypt
The database restored, but .env does not match the original deployment. Restore the original values for:
PASSWORD_ENCRYPTION_KEY
PASSWORD_PREVIOUS_KEYS
MFA_ENCRYPTION_KEY
INTEGRATION_SECRET_KEY
SMTP_SECRET_KEY
If these keys are lost, encrypted vault values cannot be recovered from the database dump.
Attachments Are Missing
The database references files that are not present under $DATA_DIR/files. Restore the file backup again and confirm ownership/permissions allow the api container to read the directory.
Backup Runs Keep Only One Dump Per Day
Increase Keep last in the backup schedule. Daily / weekly / monthly retention is bucketed, so multiple manual runs in the same day count as one daily slot unless protected by Keep last.
Checklist
- At least one scheduled backup exists under Admin → Backups.
- A manual Run now backup has succeeded.
-
$DATA_DIR/backupis copied off-host. -
$DATA_DIR/filesis copied off-host. -
.envis stored securely outside the Docker host. - Off-host backups are encrypted.
- A restore has been tested on a clean host.