Savvy Docs

Backups

Back up and restore Savvy's SQLite database safely. The database runs in WAL mode, so checkpoint the WAL before copying the file — or use the built-in backups.

Savvy stores everything in a single SQLite database in the /data volume. Backing it up is just a matter of copying that file safely.

The simplest, safest option: create, restore and download backups directly from the UI under Settings → Backups. This handles the WAL checkpoint for you, so you always get a consistent file.

Why you can't just copy the file

WAL mode

The database runs in WAL mode, so recent writes may still live in the database.sqlite-wal file and won't be in database.sqlite yet. Copying database.sqlite alone can silently lose your latest data. Always checkpoint the WAL into the main file first (or use the in-app backup, which does this for you).

Manual backup

Fold the WAL into the main file, then copy it out:

# Fold the WAL into the main file, then copy
docker exec savvy php artisan tinker --execute="DB::statement('PRAGMA wal_checkpoint(TRUNCATE);');"
docker cp savvy:/data/database.sqlite ./backup-$(date +%Y%m%d).sqlite

Restore

Stop the writers first so the WAL doesn't fight the swap:

docker compose down
docker cp ./backup.sqlite savvy:/data/database.sqlite
docker compose up -d

Scheduling backups

Community example — verify before use

This cron wrapper is a convenience example built around the manual backup commands above, not part of the project's docs. Test it end-to-end (including a restore) before trusting it.

To take a nightly off-container backup, wrap the checkpoint-and-copy in a cron job on the host (here, every day at 03:00, keeping the last 14 days):

# /etc/cron.d/savvy-backup
0 3 * * * root docker exec savvy php artisan tinker --execute="DB::statement('PRAGMA wal_checkpoint(TRUNCATE);');" && docker cp savvy:/data/database.sqlite /backups/savvy/backup-$(date +\%Y\%m\%d).sqlite && find /backups/savvy -name 'backup-*.sqlite' -mtime +14 -delete

Store the resulting files off the host (object storage, another machine) so a disk failure doesn't take your backups with it.

On this page