Backups
To fully protect your NocoDB instance, back up these three items:
- the Postgres database (your data and metadata)
- the attachments volume (uploaded files)
- your config files (to rebuild the stack quickly)
What to back up
| Item | Where it lives | Why |
|---|---|---|
| Postgres database | Bundled: postgres_data named volume / External: your DB host | Contains all your bases, tables, rows, users and comments |
| Attachments | nocodb_data named volume (mounted at /usr/app/data) | Files users uploaded to attachment fields |
| Configuration | docker-compose.yml, docker.env, nocodb/db.json | Lets you rebuild the same stack on a new 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).sqlTo restore on a new stack:
cat backup-20260509.sql | docker compose exec -T db psql -U nocodb nocodbTo schedule daily backups, use 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.gzExternal (managed) Postgres
If you use RDS, Cloud SQL, Azure Database or another managed service, use the snapshot/backup mechanism of the provider. Managed providers do this much better than pg_dump:
- AWS RDS: Automated backups (recommended) + manual snapshots before major upgrades.
- Google Cloud SQL: Automated backups and on-demand backups.
- Azure Database for PostgreSQL: Backup and restore.
For a self-managed external Postgres, run pg_dump from a host that can reach your DB.
Attachments
By default, NocoDB stores attachments on the local filesystem, in the nocodb_data named volume. Compose adds the deployment directory name before volume names. Thus, find the real name first:
docker volume ls | grep _nocodb_data # e.g. nocodb_nocodb_dataBack up the volume with a temporary helper container. The container 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 configured S3-compatible object storage (NC_S3_* env vars), your attachments are in that bucket, not in the nocodb_data volume. The volume backup above then does not apply. Back up the bucket instead, with the tools of your storage provider. For example, enable bucket versioning, lifecycle or cross-region replication rules, or scheduled bucket snapshots.
Config files
Keep these three files in version control:
docker-compose.yml
docker.env
nocodb/db.jsonIf your server is destroyed, restore it in this sequence: 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
- Provision a new Linux VM with Docker.
- Run the Single-server install with the same domain settings.
- Stop NocoDB, so that the database is idle:
docker compose stop nocodb worker. - Restore Postgres:
cat backup.sql | docker compose exec -T db psql -U nocodb nocodb. - 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. - Restart:
docker compose start nocodb worker.
The recovery time depends on the size of your database dump and attachments. A small instance restores in minutes.
Last updated on