https://github.com/pjiaquan/nocodb-postgres-boilerplate
Schema-first NocoDB + PostgreSQL boilerplate with automatic bootstrap
https://github.com/pjiaquan/nocodb-postgres-boilerplate
boilerplate docker-compose nocodb postgresql schema-first
Last synced: 5 days ago
JSON representation
Schema-first NocoDB + PostgreSQL boilerplate with automatic bootstrap
- Host: GitHub
- URL: https://github.com/pjiaquan/nocodb-postgres-boilerplate
- Owner: pjiaquan
- License: mit
- Created: 2026-03-21T11:03:41.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-03-21T11:25:38.000Z (2 months ago)
- Last Synced: 2026-03-22T02:24:31.590Z (2 months ago)
- Topics: boilerplate, docker-compose, nocodb, postgresql, schema-first
- Language: Shell
- Size: 12.7 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# NocoDB PostgreSQL Boilerplate
Schema-first boilerplate for teams that want PostgreSQL as the source of truth and NocoDB as the UI layer, without manual NocoDB bootstrap steps.
This template gives you:
- PostgreSQL + Redis + NocoDB via Docker Compose
- SQL migrations as the only approved schema path
- automatic base creation, PostgreSQL integration, source binding, and metadata sync
- hard-fail startup when `.env` or required variables are missing
- bind-mounted local data directories under `./data`
It does not generate custom NocoDB UI metadata such as forms, views, or shared links.
## What Happens On Startup
On `docker compose up -d --build`, the stack automatically:
1. starts PostgreSQL and Redis
2. runs SQL migrations
3. starts NocoDB
4. signs in with the admin account from `.env`
5. creates or reuses the NocoDB base
6. creates or reuses the PostgreSQL integration
7. binds the base source to `APP_SCHEMA`
8. clears NocoDB metadata cache
9. triggers metadata sync
You do not need to click `Create Base`, `Connect External Data`, or `Meta Sync`.
## Use This Template
Recommended flow for a new project:
1. Create a new repository from this boilerplate, or copy it into a new repo.
2. Rename the project-level settings in `.env`, especially:
- `COMPOSE_PROJECT_NAME`
- `APP_SCHEMA`
- `NOCODB_BASE_TITLE`
- `NOCODB_INTEGRATION_TITLE`
- `NC_PUBLIC_URL`
3. Replace `db/migrations/0001_init_app.sql` with your real initial schema.
4. Start the stack and confirm the example bootstrap works in your new repo.
5. Make your first project-specific commit before adding business logic or extra services.
## Quick Start
1. Copy the env template.
```bash
cp .env.example .env
```
2. Change at least:
- `POSTGRES_PASSWORD`
- `REDIS_PASSWORD`
- `NC_AUTH_JWT_SECRET`
- `NC_ADMIN_EMAIL`
- `NC_ADMIN_PASSWORD`
- `NC_PUBLIC_URL`
3. Start the stack.
```bash
docker compose up -d --build
```
4. Check status.
```bash
docker compose ps
docker compose logs migrate
docker compose logs bootstrap
```
5. Open NocoDB and sign in with `NC_ADMIN_EMAIL` and `NC_ADMIN_PASSWORD`.
The base should already exist, and the example table should already be visible.
If `bootstrap` exits early, check `docker compose logs bootstrap` first. The most common cause is that NocoDB accepted TCP connections later than Compose marked the service as started. This boilerplate now waits for a NocoDB healthcheck and keeps retrying sign-in until timeout.
## What You Replace First
Before using this as a real project, replace or adjust:
1. `db/migrations/0001_init_app.sql`
2. `APP_SCHEMA` in `.env`
3. `NOCODB_BASE_TITLE`
4. `NOCODB_INTEGRATION_TITLE`
5. `NC_PUBLIC_URL`
6. any example tables or views you do not want
## Repository layout
- `.env.example`: required environment variables
- `docker-compose.yml`: stack definition
- `bootstrap/Dockerfile`: bootstrap image
- `scripts/bootstrap_nocodb.sh`: NocoDB bootstrap flow
- `scripts/update_schema_snapshot.sh`: refresh schema snapshot
- `scripts/check_schema_drift.sh`: compare live schema with snapshot
- `db/migrations`: SQL migrations
- `data/postgres`: PostgreSQL data
- `data/redis`: Redis data
- `data/nocodb`: NocoDB local data
PostgreSQL uses `PGDATA=/var/lib/postgresql/data/pgdata`, so the bind-mounted `data/postgres` root can safely contain mount-point metadata or a tracked `.gitkeep`. If you previously saw `initdb: error: directory "/var/lib/postgresql/data" exists but is not empty`, clear `data/postgres` and start again.
## Current defaults
The boilerplate ships with:
- `APP_SCHEMA=app`
- base title `App Data`
- integration title `App PostgreSQL`
- one example table: `example_records`
- one example view: `v_example_record_counts`
The example migration is intentionally small. Replace it with your real domain schema.
## Why this boilerplate uses a dedicated schema
NocoDB stores its own metadata tables in PostgreSQL. If your business tables live in the same scanned schema, NocoDB can import its own `nc_*` tables during metadata sync.
This boilerplate avoids that by keeping business tables in a dedicated schema, defaulting to `app`.
## Why the bootstrap script touches NocoDB metadata tables
The current bootstrap flow uses a mix of:
- NocoDB API calls for auth, workspace lookup, base creation, and integration creation
- direct PostgreSQL updates to `nc_integrations_v2` and `nc_sources_v2` for deterministic source rebinding
That choice is deliberate. It avoids the manual UI flow and worked more reliably than relying on the source-binding API flow alone.
If a future NocoDB release changes these metadata tables, the bootstrap script may need adjustment.
## Hard-fail behavior
If `.env` is missing, or required variables are missing, `docker compose` fails immediately with a clear interpolation error such as:
```text
required variable DATABASE_URL is missing a value
```
It does not continue with blank values.
## Common commands
Start:
```bash
docker compose up -d --build
```
Stop:
```bash
docker compose down
```
Re-run migrations:
```bash
docker compose run --rm migrate --wait --wait-timeout 120s --migrations-dir /db/migrations --no-dump-schema up
```
Re-run bootstrap:
```bash
docker compose run --rm bootstrap
```
Update schema snapshot:
```bash
bash scripts/update_schema_snapshot.sh
```
Check schema drift:
```bash
bash scripts/check_schema_drift.sh
```
## Reset a disposable local environment
This boilerplate uses bind mounts under `./data`.
To reset local state:
1. stop the stack
2. delete `data/postgres`, `data/redis`, and `data/nocodb`
3. run `docker compose up -d --build` again
## Suggested next step
After cloning this boilerplate for a real project, make your first commit with:
- renamed base title
- renamed schema if needed
- replaced initial migrations
- updated README