Nodaro Docs
DocumentationNode ReferenceModelsAI Agents (MCP)DevelopersSelf-hostingResearch

Backups and restore

Back up a self-hosted Nodaro with one command, restore it with another and downgrade safely. Learn what the archive holds and how to protect its key.

A self-hosted Nodaro is backed up with one command and restored with another. The backup archive holds everything the stack cannot regenerate: the database, your media, the instance encryption key and your .env. The restore is also the only way to downgrade, because the database migrations only move forward. Returning to an earlier version means restoring the backup you took before the update.

What a backup contains

tools/community-backup.sh writes one tar.gz archive:

In the archiveWhat it is
db.dumpPostgres, in pg_dump's custom format: workflows, users, jobs and media records
minio-data.tarYour generated media: images, videos and audio
encryption-keyThe instance key that encrypts provider keys and social sign-in tokens. A database restored without it holds rows nobody can read.
envYour .env: provider keys and secrets
manifest.jsonThe app version and the time of the backup, for the restore script

Redis is left out on purpose: it holds only short-lived job state.

The archive is a credential

It contains your .env and the encryption key. The script restricts the file to its owner (chmod 600). Keep it that way, and store the archive like a password. On Windows, chmod has no real effect: keep the file out of synced folders and shared drives, and restrict it with NTFS permissions if other people use the computer.

Take a backup

From your install directory, where docker-compose.community.yml is, with the stack running:

tools/community-backup.sh
# -> ./backups/nodaro-backup-<date>-v<version>.tar.gz
OptionWhat it does
tools/community-backup.sh /path/to/backupsWrites the archive to another directory
COMPOSE_FILE=my-compose.yml tools/community-backup.shUses a compose file with another name

The script prints what went into the archive. If the encryption key is missing, it says so loudly and exits with an error, so a scheduled job notices. That archive cannot restore your provider keys.

The database dump is always consistent. Media written while the backup runs may miss the archive. For a guaranteed-consistent media snapshot, stop the app first:

docker compose -f docker-compose.community.yml stop nodaro

On Windows, run the scripts from Git Bash, the shell that Git for Windows installs. PowerShell and the bash of WSL break the container paths.

When to back up

Before every major version update, where the first number changes, and on whatever schedule your data deserves. A cron line works as it is:

0 3 * * * cd /path/to/install && tools/community-backup.sh >> backup.log 2>&1

Restore a backup

tools/community-restore.sh backups/nodaro-backup-<date>-v<version>.tar.gz

The restore replaces the database and the media with the archive's contents, so it asks you to type RESTORE before it touches anything. Then it:

  1. Stops the app and the database clients, auth and rest, because their open connections would block the restore.
  2. Restores Postgres and checks that it works, instead of trusting exit codes. Some harmless messages from the Supabase image are expected and printed.
  3. Restores the media and checks that the buckets are back and MinIO is healthy. Then it restores the encryption key and checks its size on the volume. Then it restores your .env, after saving any existing .env aside. A failed check stops the script before the app starts: starting without the right key would create a new one and make every restored provider key unreadable for good.
  4. Starts everything again and waits for the app's own health check. The script reports success only once the app is up, and exits with an error otherwise.

When it finishes, open http://localhost:3000/setup. Every card should be green.

Downgrade a version

There is no migration rollback. To return to an earlier version:

  1. Restore the backup taken before the update, as above.
  2. Pin the older image, for example ghcr.io/nodaroai/nodaro-community:v1.25.1, in NODARO_IMAGE or in docker-compose.community.yml. Exact vX.Y.Z tags never move.
  3. Run docker compose -f docker-compose.community.yml up -d nodaro.

See Updating for the tags.

Back up a managed deployment

Outside the compose stack, four things hold state:

WhatHow to protect it
Supabase Postgres: workflows, profiles, jobs and media recordsUse Supabase's point-in-time recovery, on paid plans, or run pg_dump regularly. This is the backup that matters most.
The storage bucket: generated images, videos and audioEnable bucket versioning and a long lifecycle rule so deleted files can be recovered. Add cross-region replication for disaster recovery if you need it.
RedisNothing to back up. It holds only short-lived job state. If you lose it, runs in progress fail, and everything else recovers from Postgres on the next start.
The instance encryption key, NODARO_ENCRYPTION_KEYKeep it with the Postgres backups. Without it, the restored rows of provider keys, social sign-in tokens and Webhook Output credentials cannot be read. The tiles then show missing and the keys must be entered again; nothing else breaks.

If Postgres is down during a migration or a recovery, the API restarts in a loop until it can reach the database. Once Postgres is back, restart the Nodaro container.

Troubleshooting

  • the db service is not running. Start the stack first: docker compose -f docker-compose.community.yml up -d.
  • Provider keys show missing after 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 enter the keys again on /setup.
  • Restore verification failed. The script refuses to leave a half-restored database silently. Run the restore again. If it fails repeatedly, the archive may be truncated: compare its size with the original.
  • could not read the encryption key during a backup on Windows. You are not in Git Bash, or the app container is not running. Run the backup again from Git Bash with the stack up. The archive the script warned about is not a usable backup.
  • media restore verification FAILED or encryption key verification FAILED. The script stopped on purpose and did not start the app. Check 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.

Frequently asked questions

Last updated on

On this page