Backups

Back up your NocoDB instance: Postgres data, attachments, and config.

Back up three things to fully protect your NocoDB instance: the Postgres database (your data and metadata), the attachments volume (uploaded files), and your config files (so you can rebuild the stack quickly).

What to back up

ItemWhere it livesWhy
Postgres databaseBundled: postgres_data named volume / External: your DB hostContains all your bases, tables, rows, users, comments
Attachmentsnocodb_data named volume (mounted at /usr/app/data)Files users uploaded to attachment fields
Configurationdocker-compose.yml, docker.env, nocodb/db.jsonLets you rebuild the same stack on a fresh server

Named volumes persist across restarts and docker compose down. But a volume on the same host is not a backup. Always copy database dumps and attachment archives off the server.

Bundled Postgres

If you used --pg=bundled (or the Quickstart compose), back up the database container with pg_dump:

cd nocodb  # your deployment directory
docker compose exec db pg_dump -U nocodb nocodb > backup-$(date +%Y%m%d).sql

Restore on a fresh stack:

cat backup-20260509.sql | docker compose exec -T db psql -U nocodb nocodb

Schedule daily backups with cron:

# /etc/cron.d/nocodb-backup
0 3 * * * root cd /opt/nocodb && docker compose exec -T db pg_dump -U nocodb nocodb | gzip > /backups/nocodb-$(date +\%Y\%m\%d).sql.gz

External (managed) Postgres

If you're using RDS, Cloud SQL, Azure Database, or another managed service, use the provider's snapshot/backup mechanism. Managed providers handle this far better than pg_dump:

For self-managed external Postgres, run pg_dump from a host that can reach your DB.

Attachments

If your NocoDB stores attachments on the local filesystem (default), they live in the nocodb_data named volume. Compose prefixes volume names with the deployment directory, so confirm the real name first:

docker volume ls | grep _nocodb_data   # e.g. nocodb_nocodb_data

Back it up with a throwaway helper container that mounts the volume read-only:

docker run --rm \
  -v nocodb_nocodb_data:/data:ro \
  -v "$(pwd)":/backup \
  alpine tar -czf /backup/attachments-$(date +%Y%m%d).tar.gz -C /data .

If you've configured S3-compatible object storage (NC_S3_* env vars), your attachments live in that bucket rather than the nocodb_data volume, so the volume backup above doesn't apply. Back up the bucket instead, using your storage provider's tools: enable bucket versioning, lifecycle or cross-region replication rules, or scheduled bucket snapshots.

Config files

Track these three files in version control:

docker-compose.yml
docker.env
nocodb/db.json

If your server is destroyed, restoring is: provision new server → install Docker → git clone your config repo → docker compose up -d → restore Postgres dump → restore attachments tarball.

Don't commit secrets. docker.env and nocodb/db.json contain credentials. Use a private repo, encrypt with git-crypt or sops, or store secrets separately and template the files at deploy time.

Restoring on a new server

  1. Provision a fresh Linux VM with Docker.
  2. Run the Single-server install with the same domain settings.
  3. Stop NocoDB so the database is idle: docker compose stop nocodb worker.
  4. Restore Postgres: cat backup.sql | docker compose exec -T db psql -U nocodb nocodb.
  5. Restore attachments into the volume: docker run --rm -v nocodb_nocodb_data:/data -v "$(pwd)":/backup alpine tar -xzf /backup/attachments.tar.gz -C /data.
  6. Restart: docker compose start nocodb worker.

Recovery time scales with the size of your database dump and attachments; a small instance restores in minutes.