Backup & restore
One command each way. The backup is also the only downgrade path — database migrations are forward-only, so “going back a version” means restoring the backup you took before upgrading.
What a backup contains
tools/community-backup.sh produces a single tar.gz holding everything your stack cannot regenerate.
.env — provider keys and secretsRedis is deliberately absent — it holds only ephemeral job state.
.env and the encryption key. The script chmods it 600; keep it that way, and store it like a password. On Windows that chmod has no real effect — keep the file out of synced folders and shared drives, and restrict it with NTFS permissions if others use the PC.Windows: run both scripts from Git Bash (installed with Git for Windows) — not PowerShell, and not WSL's bash, which sees a different filesystem. The scripts print what actually went into the archive; if the encryption key is missing the backup says so loudly and exits non-zero (so a cron job notices), and that archive cannot restore your provider keys.
Taking a backup
From your install directory (where docker-compose.community.yml lives), with the stack running:
tools/community-backup.sh
# -> ./backups/nodaro-backup-<date>-v<version>.tar.gz
tools/community-backup.sh /path/to/backupsa different output directory
COMPOSE_FILE=my-compose.yml tools/community-backup.sha non-default compose file
For a guaranteed-consistent media snapshot, stop the app first (docker compose -f docker-compose.community.yml stop nodaro) — media written while the dump runs may miss the archive; the database dump is always consistent either way.
When to back up: before every major-version upgrade (the first number changed), and on whatever schedule your data deserves. A cron line works as-is:
0 3 * * * cd /path/to/install && tools/community-backup.sh >> backup.log 2>&1
Restoring
tools/community-restore.sh backups/nodaro-backup-<date>-v<version>.tar.gz
The script:
- 1Stops the app and the database clients (
auth,rest) — their live connections would block the restore. - 2Restores Postgres and verifies it functionally — it does not trust exit codes; some harmless supabase-image noise is expected and printed.
- 3Restores the media store and verifies it (buckets back in place, MinIO healthy again), then the encryption key and verifies it (byte count on the volume), then your
.env(an existing.envis saved aside first). A failed verification stops the script before the app starts — booting without the right key would mint a new one and make every restored provider key unreadable for good. - 4Restarts everything and waits for the app's own health check — the script only says “complete” once the app is actually up (a non-zero exit otherwise).
RESTORE before touching anything.When it finishes, open http://localhost:3000/setup — every card should be green.
Downgrading a version
There is no migration rollback. To go back:
- 1Restore the backup taken before the upgrade (above).
- 2Pin the older image tag in
docker-compose.community.yml(e.g.ghcr.io/nodaroai/nodaro-community:v1.25.1— exactvX.Y.Ztags are immutable) and rundocker compose up -d nodaro.
Troubleshooting
- “the db service is not running”
- Start the stack first:
docker compose -f docker-compose.community.yml up -d. - Provider keys show
missingafter a restore - The database was restored without its matching
encryption-key(or with a different one). Restore from an archive that has the key, or re-enter the keys on/setup. - Restore verification failed
- The script refuses to leave a half-restored database silently; re-run the restore. If it fails repeatedly, the archive may be truncated — check its size against the original.
- “could not read the encryption key” during a backup on Windows
- You are not in Git Bash (PowerShell and WSL both break the container paths), or the app container is not running. Re-run from Git Bash with the stack up; the archive the script printed a warning for is not a usable backup.
- “media restore verification FAILED” / “encryption key verification FAILED”
- The script stopped on purpose and did not start the app. Inspect the volume it names, fix the cause (usually a stopped container or a full disk), and run the restore again — it is safe to repeat.