Self-Hosting NocoDB with Docker Compose
What Is NocoDB?
NocoDB turns any database into a smart spreadsheet interface. Think Airtable, but running on your own server with your own data. It connects to PostgreSQL, MySQL, SQLite, or SQL Server and gives you views, forms, automations, and a REST API — all without writing code. It replaces Airtable and similar no-code database tools.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 2 GB of free RAM (1 GB minimum for small deployments)
- 5 GB of free disk space
- A domain name (optional, for remote access)
Docker Compose Configuration
This setup uses PostgreSQL as the database backend, which is recommended for production. NocoDB can use SQLite by default, but PostgreSQL handles concurrent users and larger datasets better.
Create a docker-compose.yml:
services:
nocodb:
image: nocodb/nocodb:0.301.2
container_name: nocodb
depends_on:
db:
condition: service_healthy
environment:
NC_DB: "pg://db:5432?u=nocodb&p=changeme_strong_password&d=nocodb" # CHANGE password
NC_AUTH_JWT_SECRET: "changeme_generate_with_openssl_rand" # CHANGE — run: openssl rand -base64 32
NC_PUBLIC_URL: "http://localhost:8080" # Set to your actual URL for email links and API docs
NC_DISABLE_TELE: "true" # Disable anonymous telemetry
NC_DISABLE_ERR_REPORTS: "true" # Disable Sentry error reporting
volumes:
- nocodb-data:/usr/app/data # Application data, uploads, metadata
ports:
- "8080:8080" # Web UI and API
restart: unless-stopped
db:
image: postgres:16.6
container_name: nocodb-db
environment:
POSTGRES_DB: nocodb
POSTGRES_USER: nocodb
POSTGRES_PASSWORD: changeme_strong_password # CHANGE — must match NC_DB above
volumes:
- nocodb-db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U nocodb"]
interval: 10s
timeout: 5s
retries: 10
restart: unless-stopped
volumes:
nocodb-data:
nocodb-db-data:
Before starting: Generate a JWT secret and set a strong database password:
# Generate JWT secret
openssl rand -base64 32
# Generate database password (avoid special characters — NocoDB limitation)
openssl rand -hex 16
Replace both changeme values in the compose file, and update NC_PUBLIC_URL to your actual access URL.
Start the stack:
docker compose up -d
Initial Setup
- Open
http://your-server-ip:8080in your browser - Create your admin account (email + password)
- You’ll land on the dashboard — create your first base (NocoDB’s term for a database project)
- Choose “Create from scratch” or import from Airtable (NocoDB has a built-in Airtable importer)
Feature Overview
| Feature | Details |
|---|---|
| Views | Grid, Gallery, Kanban, Form, Calendar |
| Field types | 22+ including Links, Lookup, Rollup, Formula, Barcode, QR Code |
| API | Auto-generated REST API for every table |
| Automations | Webhook triggers, email notifications, Slack/Discord/Teams integration |
| Roles | Owner, Creator, Editor, Commenter, Viewer |
| Import/Export | CSV, Excel, Airtable, JSON |
| Shared views | Public links with optional password protection |
| Audit log | Full change history per record |
Configuration
Connect to an Existing Database
NocoDB can sit on top of an existing PostgreSQL or MySQL database. Instead of creating tables from scratch, it reads your existing schema and provides a spreadsheet interface:
NC_DB: "pg://your-existing-db-host:5432?u=readonly_user&p=password&d=your_database"
This is NocoDB’s killer feature — turn any legacy database into a collaborative spreadsheet without migrating data.
Email Notifications
Add SMTP configuration to enable email notifications and invites:
environment:
NC_SMTP_FROM: "[email protected]"
NC_SMTP_HOST: "smtp.example.com"
NC_SMTP_PORT: "587"
NC_SMTP_USERNAME: "[email protected]"
NC_SMTP_PASSWORD: "smtp-password"
NC_SMTP_SECURE: "true"
Increase Upload Size
The default upload limit is 20 MB. Increase it for larger file attachments:
environment:
NC_ATTACHMENT_FIELD_SIZE: 52428800 # 50 MB in bytes
Redis for Caching (Optional)
For better performance with multiple concurrent users, add Redis:
services:
redis:
image: redis:7.4
container_name: nocodb-redis
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
nocodb:
environment:
NC_REDIS_URL: "redis://redis:6379"
depends_on:
redis:
condition: service_healthy
Reverse Proxy
Put NocoDB behind a reverse proxy for HTTPS. Caddy example:
nocodb.example.com {
reverse_proxy localhost:8080
}
See our Reverse Proxy Guide for Nginx Proxy Manager and Traefik configurations.
Backup
Back up both the PostgreSQL database and NocoDB’s data volume:
# Database dump
docker exec nocodb-db pg_dump -U nocodb nocodb > nocodb-backup-$(date +%Y%m%d).sql
# Application data (uploads, metadata)
docker run --rm -v nocodb-data:/data -v $(pwd):/backup \
alpine tar czf /backup/nocodb-data-$(date +%Y%m%d).tar.gz /data
Restore from backup:
# Restore database
cat nocodb-backup-20260224.sql | docker exec -i nocodb-db psql -U nocodb nocodb
# Restore data volume
docker run --rm -v nocodb-data:/data -v $(pwd):/backup \
alpine tar xzf /backup/nocodb-data-20260224.tar.gz -C /
See our Backup Strategy Guide for automated approaches.
Troubleshooting
”Invalid JWT Secret” After Container Recreation
Symptom: All users are logged out after recreating the NocoDB container. API tokens stop working.
Fix: You didn’t set NC_AUTH_JWT_SECRET explicitly. NocoDB auto-generates a new secret on every container start if one isn’t provided. Set it permanently in your compose file and redeploy:
echo "NC_AUTH_JWT_SECRET=$(openssl rand -base64 32)" >> .env
docker compose up -d
Database Connection Refused
Symptom: NocoDB logs show “ECONNREFUSED” or “connection refused” for PostgreSQL.
Fix: The depends_on with service_healthy should prevent this, but if PostgreSQL is slow to start:
# Check if PostgreSQL is running
docker logs nocodb-db
# Restart NocoDB after PostgreSQL is healthy
docker compose restart nocodb
Airtable Import Fails
Symptom: Import stalls or returns errors for large Airtable bases.
Fix: Large imports (100+ tables or 100K+ records) may time out. Import in smaller batches by selecting fewer tables at a time. Also ensure NC_ATTACHMENT_FIELD_SIZE is large enough for any file attachments in the Airtable base.
Permission Errors on Volume
Symptom: NocoDB container fails to start with “EACCES” permission errors.
Fix: The NocoDB container runs as root by default, so this is rare. If using a bind mount instead of a named volume:
sudo chown -R 999:999 ./nocodb-data
Resource Requirements
| Metric | Value |
|---|---|
| RAM (idle) | ~200 MB (NocoDB) + ~100 MB (PostgreSQL) |
| RAM (active, 10+ users) | 500 MB - 1 GB |
| CPU | Low (spikes during imports and API calls) |
| Disk | ~300 MB for application + database storage |
Verdict
NocoDB is the best self-hosted Airtable alternative for most people. The ability to connect to existing databases and instantly get a spreadsheet interface is genuinely useful — it’s not just an Airtable clone, it’s a database UI tool. The Docker setup is straightforward, resource usage is light, and the auto-generated REST API means you can build applications on top of it without writing backend code.
If you need more advanced automations or a more polished UI, check out Baserow as an alternative. But for most use cases, NocoDB delivers everything Airtable does without the per-seat pricing.
Related
Get self-hosting tips in your inbox
New guides, comparisons, and setup tutorials — delivered weekly. No spam.