Skip to content

Backup and Restore

Strawly stores all of an instance's state in its PostgreSQL database: user accounts, roles, settings, inventory, metrics, recommendations, initiatives, scopes and cloud credentials. There are two ways to back it up:

In-app backup strawly backup
Where Settings > Database Usage in the browser The server's terminal
File One encrypted .strawly file, protected by a passphrase you choose A pg_dump file in the instance's backups/ folder
Restores on another server Yes, with any encryption key Only with the same CREDENTIALS_ENCRYPTION_KEY for the stored credentials
Used by Moving Strawly, first-run restore strawly upgrade and strawly rollback, scheduled backups

In-app backup and restore

Users with the Back up and restore the database permission (data:backup:manage, part of the Settings Manager role) can back up and restore Strawly from Settings > Database Usage, without shell access to the server.

Download a backup

Select Download backup and set a passphrase of at least 12 characters. The browser downloads a file named after the server time in UTC, for example strawly-2026-10-03-161202.strawly.

The file contains every table in the public and azure schemas: users, password hashes, roles, settings, inventory, metrics, recommendations, initiatives and logs. It does not contain the migration history (_prisma_migrations) or the pg-boss job queue, which the module services recreate on start.

The file is encrypted with AES-256-GCM, using a key derived from the passphrase with scrypt. Cloud credentials and the SMTP password are stored in the file in decrypted form, inside that encryption, so the backup does not depend on CREDENTIALS_ENCRYPTION_KEY. A backup cannot be restored without its passphrase, and Strawly cannot recover a lost passphrase.

Restore a backup

Select Restore from backup, choose the .strawly file and enter its passphrase. Strawly decrypts and checks the whole file before changing anything, then shows the row counts of the backup next to the current data, the accounts that will hold the Settings Manager role, and any warnings. Type RESTORE to confirm.

A restore replaces all data. Nothing is merged. In order, Strawly:

  1. Pauses collector runs. A restore is refused while a collector run is in progress.
  2. Saves a copy of the current data to BACKUP_DIR as strawly-<timestamp>-pre-restore.strawly, encrypted with the same passphrase. The last three copies are kept.
  3. Empties every table and loads the backup in a single database transaction. If any step fails, the transaction is rolled back and the current data stays as it was.
  4. Encrypts the cloud credentials and SMTP password again with this server's CREDENTIALS_ENCRYPTION_KEY.
  5. Signs out every session. Everyone signs in again with an account from the backup.

To undo a restore, restore the pre-restore copy from BACKUP_DIR. Mount BACKUP_DIR as a volume so the copies survive a container restart.

A backup can be restored into the same version of Strawly or a newer one. A backup made by a newer version is refused, because its schema is ahead of the running deployment. Update the deployment first.

Restore on a new deployment

When an administrator signs in to a deployment that has no data yet, Strawly asks whether to restore a backup or start blank. Choosing Restore from a backup opens the same restore steps. To move Strawly to a new server, download a backup on the old server, deploy the new one, sign in with the ADMIN_EMAIL account, and restore. The new server can use its own CREDENTIALS_ENCRYPTION_KEY.

For scheduled backups on the server, use the command-line backups below.

Backups from the command line

strawly backup

This writes backups/manual-<date>-<time>.dump in the instance folder (/opt/strawly/instances/<name>/). strawly upgrade writes one the same way, named pre-upgrade-..., before every upgrade.

The dump is not encrypted, and stored cloud credentials inside it are readable only with the instance's CREDENTIALS_ENCRYPTION_KEY. Keep a copy of the instance's .env with the dumps, in a place with restricted access.

Scheduled backups

Add a daily backup at 02:00 to the root crontab (sudo crontab -e):

0 2 * * * /usr/local/bin/strawly backup -i strawly >> /var/log/strawly-backup.log 2>&1

Delete dumps older than 30 days:

30 2 * * * find /opt/strawly/instances/strawly/backups -name "manual-*.dump" -mtime +30 -delete

Copy the backups to another machine or to object storage. A backup on the same disk does not help if the server is lost.

Restoring a dump

To undo the last upgrade, use strawly rollback. It restores the pre-upgrade dump and the previous versions together.

To restore any other dump, stop Strawly, replace the database and start again:

strawly stop
strawly compose up -d postgres
strawly compose exec -T postgres sh -c 'psql -U "$POSTGRES_USER" -d postgres -c "DROP DATABASE \"$POSTGRES_DB\" WITH (FORCE)" -c "CREATE DATABASE \"$POSTGRES_DB\" OWNER \"$POSTGRES_USER\""'
strawly compose exec -T postgres sh -c 'pg_restore -U "$POSTGRES_USER" -d "$POSTGRES_DB" --no-owner' < /opt/strawly/instances/strawly/backups/manual-2026-10-03-020000.dump
strawly apply

Restore a dump with the same Strawly version that made it, or an older dump into a newer version. A dump made by a newer version cannot run on an older one.