Backup and Restore¶
Strawly stores all state in PostgreSQL: user accounts, roles, inventory data, recommendations, initiatives, scopes, and cloud provider credentials. No state lives inside Docker containers or volumes outside the database. A pg_dump of the strawly database is a complete backup.
What to back up¶
Two things are required to restore a working Strawly instance:
- The database dump — produced by
pg_dump, contains all rows. CREDENTIALS_ENCRYPTION_KEYfrom.env— cloud provider credentials stored in the database are encrypted with this key. A dump restored without the matching key leaves those credentials unreadable.
Back up your .env file alongside each database dump. That covers both requirements.
Dump files are sensitive
The dump contains user data and configuration. Store backups in a location with restricted access and do not commit them to version control.
Manual backup¶
Run pg_dump inside the running strawly-postgres container:
docker exec strawly-postgres \
pg_dump -U strawly -d strawly -Fc \
> ~/strawly-backups/strawly_$(date +%Y%m%d_%H%M%S).dump
The -Fc flag produces a compressed binary format that pg_restore can use. Create the output directory first if it does not exist:
Scheduled backup¶
Add a cron job on the host to run the backup automatically. Open the crontab:
Add a line to back up daily at 02:00:
0 2 * * * mkdir -p ~/strawly-backups && docker exec strawly-postgres pg_dump -U strawly -d strawly -Fc > ~/strawly-backups/strawly_$(date +\%Y\%m\%d_\%H\%M\%S).dump 2>> ~/strawly-backups/backup.log
The % characters must be escaped as \% inside crontab entries.
To keep only the last 30 days of backups, add a second cron entry:
Restore¶
Restore replaces all data
The restore procedure drops and recreates all database objects. Any data written after the backup was taken will be lost.
Stop the backend before restoring to prevent writes during the operation:
Copy the dump file into the container and restore:
docker cp ~/strawly-backups/strawly_20260101_020000.dump strawly-postgres:/tmp/restore.dump
docker exec strawly-postgres \
pg_restore -U strawly -d strawly --clean --if-exists /tmp/restore.dump
docker exec strawly-postgres rm /tmp/restore.dump
Start the backend again:
If the backup was taken from a different environment (different CREDENTIALS_ENCRYPTION_KEY), update that value in .env to match the key used when the backup was made, then recreate the backend:
Verify the restore¶
Confirm the database contains data after restoring:
docker exec strawly-postgres \
psql -U strawly -d strawly \
-c "SELECT schemaname, tablename, n_live_tup FROM pg_stat_user_tables ORDER BY n_live_tup DESC LIMIT 10;"
The output shows live row counts per table. A successful restore shows non-zero counts in the core tables (users, roles, inventory, recommendations, and others).