NocoDB self-hosted: the Airtable alternative, and the one setting that decides if it survives a redeploy

# backend# database# opensource
NocoDB self-hosted: the Airtable alternative, and the one setting that decides if it survives a redeployGreat Sage

NocoDB self-hosted: the Airtable alternative, and the one setting that decides if it...

NocoDB self-hosted: the Airtable alternative, and the one setting that decides if it survives a redeploy

If Airtable's per-editor pricing has ever made you wince, NocoDB is the usual answer: point it at a database and it gives you a spreadsheet-style UI on top — grid, gallery, kanban, and form views, plus a REST API auto-generated for every table. It's genuinely good at that job. It's also an "app layer," not a passive viewer — worth knowing before you commit real workflows to it.

What it actually does to your data

NocoDB doesn't just display your tables, it wraps them. Every table it creates gets its own metadata columns (row ordering, internal tracking), and by default a "deleted" row isn't gone — it's flagged, not removed. If you ever point an external BI tool or a raw SQL query at the same database, you'll see rows the NocoDB UI told you didn't exist anymore. Dropdown/select field options live in NocoDB's metadata too, not as a database constraint, so anything writing to the table directly (an API script, a n8n workflow) can insert values NocoDB never intended. None of this is a bug — it's the tradeoff of "spreadsheet UI over an arbitrary SQL schema." Know it going in, and it's fine; find out after loading production data into it, less fine.

The deployment trap that's actually avoidable

Separate from the app-layer tradeoffs above, there's a purely operational mistake that's on you, not NocoDB: NC_DB decides where your metadata lives, and if you leave it unset it defaults to SQLite inside the container. That's not just "your bases" — it's every user account, every view, every shared link, every API token. On a platform like Railway where a redeploy gets a fresh container filesystem, an unset NC_DB means your entire instance — logins included — resets to zero on the next push. It's the same shape of trap PocketBase deployers hit with an unmounted volume, except here it also takes out auth, not just data.

The fix is boring: point NC_DB at a real Postgres instance from the first boot, and give that Postgres its own volume so its data directory survives too.

Deploying it without hitting that

I maintain a Railway template for this — full disclosure, I get a kickback if you deploy through it: https://railway.com/deploy/nocodb-airtable-al-1?referralCode=Z1xivh&utm_medium=integration&utm_source=template&utm_campaign=devto

Two services: NocoDB itself, and a Postgres 17 instance wired in as NC_DB from boot, both on persistent volumes (Postgres's data directory, and a second volume at /usr/app/data for file attachments — those are written to disk, not the database, so they need their own mount). The auth secret is generated once and pinned rather than left to regenerate on restart, which would otherwise invalidate every session and API token you'd issued.

If you'd rather not go through the template, it's the same idea on any Docker host:

services:
  nocodb:
    image: nocodb/nocodb:latest
    ports:
      - "8080:8080"
    environment:
      - NC_DB=pg://postgres:5432?u=nocodb&p=<password>&d=nocodb
    volumes:
      - nc_data:/usr/app/data
    depends_on:
      - postgres
  postgres:
    image: postgres:17
    environment:
      - POSTGRES_USER=nocodb
      - POSTGRES_PASSWORD=<password>
      - POSTGRES_DB=nocodb
    volumes:
      - pg_data:/var/lib/postgresql/data
volumes:
  nc_data:
  pg_data:
Enter fullscreen mode Exit fullscreen mode

Whichever way you run it, the first account you create becomes the super admin — do that immediately after boot, before anyone else can beat you to it.

Where it fits, where it doesn't

Good fit: an internal admin panel over a database your team already has, a lightweight CRM/tracker with kanban and form views, or just needing a REST API in front of tables without writing one. It's also genuinely nice for connecting to an external Postgres/MySQL/SQL Server you already run and browsing it without copying data anywhere.

Worse fit: if you need the app layer to stay invisible — clean external SQL reports, automations that write straight to the tables, or a schema you designed first and want NocoDB to just mirror without touching — its metadata injection and soft-delete behavior will fight you. If that's the actual requirement, a database-mirror tool that doesn't own the schema (or, for a pure spreadsheet feel without the DB semantics, Baserow) is the more honest choice. NocoDB is the right tool when you want the app layer; it's the wrong one when you're trying to avoid having one.