NocoDB Docker Tutorial: Turn Your SQL Database into a Smart Airtable Alternative
Setup guide to self-hosting NocoDB with Docker Compose. Connect databases, manage tables, and build spreadsheet-based interfaces.
Database Connection Strings and Parameters
NocoDB requires a primary database to store its metadata (workspace configuration, view definitions, user permissions, API keys, etc.). This metadata store is defined via the NC_DB environment variable inside the container.
Metadata Database Connection URIs
Depending on the backend engine, use the corresponding connection URI format:
- PostgreSQL:
env NC_DB=pg://<host>:<port>?u=<username>&p=<password>&d=<database_name>Example:pg://postgres-db:5432?u=nocodb_user&p=SuperSecretPassword123&d=nocodb_metadata - MySQL / MariaDB:
env NC_DB=mysql2://<host>:<port>?u=<username>&p=<password>&d=<database_name>Example:mysql2://mysql-db:3306?u=nocodb_user&p=SuperSecretPassword123&d=nocodb_metadata - SQLite: (Default, fallback if
NC_DBis not specified)env NC_DB=sqlite3:////usr/app/data/noco.db
Production Docker Compose Configurations
The following configurations outline setups using PostgreSQL and MySQL as dedicated metadata stores. Both examples utilize health checks to ensure dependencies boot in the correct order.
Option A: PostgreSQL Backend Setup
Save the following configuration as docker-compose.yml:
version: '3.8'
services:
nocodb:
image: nocodb/nocodb:latest
container_name: nocodb-app
restart: always
ports:
- "127.0.0.1:8080:8080"
environment:
# Metadata database connection
- NC_DB=pg://nocodb-pg-db:5432?u=nocodb_admin&p=db_password_987&d=nocodb_metadata
# Root URL of the NocoDB installation for links/invites
- NC_PUBLIC_URL=https://nocodb.yourdomain.com
# Secret key for JWT signing (generate a random 32-byte hex string)
- NC_AUTH_JWT_SECRET=87ef8db832cd83ad39b5d38a7c29fb721e7d2cd8e84ab4b2a8d3e12c1b827e8a
# Optimization variables
- NC_DISABLE_TELEMETRY=true
- PORT=8080
volumes:
- nc_app_data:/usr/app/data
depends_on:
nocodb-pg-db:
condition: service_healthy
nocodb-pg-db:
image: postgres:15-alpine
container_name: nocodb-pg-db
restart: always
environment:
- POSTGRES_USER=nocodb_admin
- POSTGRES_PASSWORD=db_password_987
- POSTGRES_DB=nocodb_metadata
volumes:
- nc_pg_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U nocodb_admin -d nocodb_metadata"]
interval: 10s
timeout: 5s
retries: 5
volumes:
nc_app_data:
nc_pg_data:
Option B: MySQL Backend Setup
If using MySQL for metadata, replace docker-compose.yml with:
version: '3.8'
services:
nocodb:
image: nocodb/nocodb:latest
container_name: nocodb-app
restart: always
ports:
- "127.0.0.1:8080:8080"
environment:
- NC_DB=mysql2://nocodb-mysql-db:3306?u=nocodb_admin&p=db_password_987&d=nocodb_metadata
- NC_PUBLIC_URL=https://nocodb.yourdomain.com
- NC_AUTH_JWT_SECRET=87ef8db832cd83ad39b5d38a7c29fb721e7d2cd8e84ab4b2a8d3e12c1b827e8a
- NC_DISABLE_TELEMETRY=true
- PORT=8080
volumes:
- nc_app_data:/usr/app/data
depends_on:
nocodb-mysql-db:
condition: service_healthy
nocodb-mysql-db:
image: mysql:8.0
container_name: nocodb-mysql-db
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root_password_123
- MYSQL_DATABASE=nocodb_metadata
- MYSQL_USER=nocodb_admin
- MYSQL_PASSWORD=db_password_987
volumes:
- nc_mysql_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
volumes:
nc_app_data:
nc_mysql_data:
Detailed Environment Variable Configuration
| Environment Variable | Description | Recommended/Default Value |
|---|---|---|
NC_DB |
Primary connection URI string for the NocoDB metadata store. | See database URI templates above. |
NC_PUBLIC_URL |
The external URL pointing to your NocoDB instance. Required for invitation links, dashboard redirection, and media rendering. | https://nocodb.yourdomain.com |
NC_AUTH_JWT_SECRET |
Secret key used to encrypt auth tokens. Must be generated securely (e.g., via openssl rand -hex 32). |
Random 64-character hex string |
NC_DISABLE_TELEMETRY |
Opts out of telemetry tracking if set to true. |
true |
NC_CONNECT_TO_DB_BY_URL |
Allows database source connections via raw URLs in the GUI. | true |
NC_MAX_CONTENT_LENGTH |
Limits request body size for uploads (e.g., file attachments). | 100mb |
Connecting NocoDB to Target Databases
NocoDB works by connecting to target databases containing your business data. This separation allows NocoDB metadata (views, columns, and collaborative rules) to reside in the metadata database while your core tables remain in a separate, native database.
1. Connecting via the GUI
Once logged in, click "Add New Project", select "Connect to External Database", and configure the database parameters:
- Host: Use the target database container name if on the same Docker network, or the public/private IP of the VPS.
- Port:
5432for PostgreSQL,3306for MySQL, or1433for MSSQL. - User & Password: The application database user credentials.
- Database: The target schema/database name.
2. Network Configurations for VPS Database Targets
If the target database is running on the local VPS but outside of Docker (on the host system):
Configure Host PostgreSQL to Accept Docker Connections
- Edit
/etc/postgresql/15/main/postgresql.confto allow listening on all interfaces or the docker gateway interface:
listen_addresses = '*'
- Whitelist the Docker subnet in
/etc/postgresql/15/main/pg_hba.conf:
# Type Database User Address Method
host all all 172.17.0.0/16 md5
- Restart PostgreSQL:
sudo systemctl restart postgresql
- Define the database host as
host.docker.internalinside NocoDB. To enable this resolution inside Docker, addextra_hoststo thenocodbservice indocker-compose.yml:
extra_hosts:
- "host.docker.internal:host-gateway"
Setting up Nginx Reverse Proxy with SSL
Deploying Nginx as a reverse proxy terminates TLS/SSL and redirects insecure HTTP traffic.
1. Nginx Configuration
Create /etc/nginx/sites-available/nocodb:
server {
listen 80;
server_name nocodb.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name nocodb.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/nocodb.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/nocodb.yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Enable the configuration and reload Nginx:
sudo ln -s /etc/nginx/sites-available/nocodb /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
2. Certbot SSL Configuration
Obtain a free SSL certificate from Let's Encrypt using Certbot:
sudo apt update
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d nocodb.yourdomain.com
Deployment and Maintenance Walkthrough
Step 1: Directory Setup
Create the installation directory:
mkdir -p ~/nocodb-selfhost && cd ~/nocodb-selfhost
Step 2: Initialize Docker Services
Create a docker-compose.yml file using one of the templates above, then bring up the environment in detached mode:
docker compose up -d
Confirm that the service is running and healthy:
docker compose ps
Step 3: Run Database Backups
Automate Postgres metadata backups using pg_dump:
docker compose exec -t nocodb-pg-db pg_dump -U nocodb_admin nocodb_metadata > backup_$(date +%F).sql
Step 4: Upgrading NocoDB
To upgrade the application container when new versions are released:
docker compose pull nocodb
docker compose up -d