Skip to main content

Overview

NocoDB is a no-code database and smart spreadsheet — a self-hosted alternative to Airtable, Baserow, and Teable — that turns a database into grid, kanban, gallery, and calendar views with forms, automations, and a REST API. This template deploys NocoDB Community Edition on port 8080, backed by a PostgreSQL store for all metadata, a bundled Redis, and attachments kept either on a persistent volume or in an S3 bucket you own.

Architecture

  • NocoDB server — A stateful workload running the single official image, which serves the web UI, the REST and GraphQL APIs, and live updates on port 8080. It applies its meta-database migrations automatically on boot and scales horizontally through nocodb.replicas.
  • PostgreSQL (single instance, default) — The postgres template as a subchart, running PostgreSQL 18. It holds every base, table, view, user, and automation.
  • PostgreSQL (highly available, optional) — The postgres-highly-available template instead, running PostgreSQL 17: 3× Patroni PostgreSQL with automatic failover, 3× etcd, and an HAProxy leader endpoint that NocoDB connects through.
  • Redis — A bundled single-node Redis with AOF persistence and a noeviction memory policy, deployed by this chart. It carries the job and event pub/sub, the metadata cache, and the rate limiter. NocoDB does not run without it, and all three of those roles are what make more than one replica coherent.
  • Attachment storage — Either a persistent volume mounted at /usr/app/data (default) or an S3 bucket you own.

What Gets Created

  • Stateful NocoDB Workload — The NocoDB server on port 8080 ({release}-nocodb), with nocodb.replicas replicas and configurable CPU and memory.
  • Stateful Redis Workload — The bundled single-node Redis ({release}-nocodb-redis) on port 6379 with password authentication.
  • Database Workloads — Single mode: one stateful PostgreSQL workload. HA mode: a stateful Patroni PostgreSQL workload, a stateful etcd workload, and a standard HAProxy leader-routing workload.
  • Volume Sets — One for local attachments at /usr/app/data (created only when storage.type is local), one for the Redis AOF file at /data, and the database subchart’s data volumes.
  • Secret — A template-created dictionary secret ({release}-nocodb-creds) holding the bundled Redis password used to assemble NC_REDIS_URL. Your prerequisite key secret is not created by the template — see Prerequisites.
  • Identity & Policy — One identity shared by the NocoDB and Redis workloads, and a policy granting it reveal on exactly the secrets it reads: the credentials secret, the active database’s credentials secret, your prerequisite key secret, and — when configured — the admin bootstrap, S3 static-key, and SMTP secrets. In keyless S3 mode the identity also carries the cloud account link and your bucket-scoped IAM policy.
  • Cron Backup Workload (optional) — Created inside the backing PostgreSQL store when database backups are enabled.
This template does not create a GVC. You must deploy it into an existing GVC.

Prerequisites

NocoDB signs its auth tokens and encrypts the stored credentials of external data sources with two keys that you supply through a dictionary secret created before installing. The values are never passed through Helm values.
1

Create the key secret

The secret holds two random values:
2

Point the template at it

Set secrets.name to the secret’s name (default my-nocodb-secrets). Secrets are org-level, so no GVC flag is involved.
3

Back both values up

Store a copy somewhere safe, outside Control Plane.
Create the secret before installing. Without it the deployment sits waiting on a secret that does not exist and never becomes ready, which looks like a broken install. Both keys are write-once: rotating NC_AUTH_JWT_SECRET logs out every user, and changing NC_CONNECTION_ENCRYPT_KEY makes the stored credentials of external data sources undecryptable — upstream has no re-encryption path.
Everything else works with the defaults. Four optional features need their own setup first:
  • S3 attachment storage — an existing bucket plus either a Control Plane cloud account (AWS) or a static-key secret (S3-compatible servers). See Attachment Storage. Required if you plan to run more than one replica.
  • Super-admin bootstrap — a dictionary secret holding NC_ADMIN_EMAIL and NC_ADMIN_PASSWORD. See Super-Admin Bootstrap.
  • Authenticated SMTP — a dictionary secret holding NC_SMTP_USERNAME and NC_SMTP_PASSWORD. See Email.
  • Database backups — a bucket and provider access set up beforehand. See Backing Up.
Once your key secret exists, install the template using your preferred method:

UI

Browse, install, and manage templates visually

CLI

Manage templates from your terminal

Terraform

Declare templates in your Terraform configurations

Pulumi

Declare templates in your Pulumi programs

Choosing a Database Mode

Exactly one of the two backing stores must be enabled — the chart enforces this at render. NocoDB is wired to the active database automatically, including for its boot migrations. The default is the single instance: on Control Plane it sits on a persistent volume, so a node failure reschedules it and reattaches the same volume — the difference between the two modes is minutes of downtime, not data loss. Enabling HA is one flag: set postgres.enabled: false and postgresHA.enabled: true. The two paths run different PostgreSQL majors, so pick the mode before you have data — moving an existing database between them is a pg_dump and restore, not a values change.

First Run

NocoDB ships no default account. Unless you bootstrap one, the first person to sign up becomes the super admin.
1

Wait for the workload to report ready

PostgreSQL and Redis come up first, then NocoDB applies its meta-database migrations before it starts serving. A default install typically reaches ready in about a minute; HA mode takes roughly six, most of it Patroni electing a leader.
2

Ignore a single crash line on a fresh install

On a cold install a replica can start before PostgreSQL and Redis are accepting connections, log [ioredis] … write EPIPE followed by Error: Connection terminated unexpectedly, and exit. It restarts automatically and comes up clean about twenty seconds later. One such restart on a first install is expected.
3

Sign up and claim the super-admin account

Browse to the canonical *.cpln.app endpoint of the {release}-nocodb workload and create the first account. It receives the super role. Do this as soon as the workload is ready.
4

Close signup

Signup is open by default. Turn on invite-only in Team & Settings inside the app — it is an in-app setting, not a template value.
5

Configure email before inviting anyone

Member invitations and password resets are delivered only by email. Configure SMTP before you invite your team.

Configuration

The default values.yaml for this template:

NocoDB Server

  • image — The official NocoDB image. Pin a released tag.
  • replicas — Number of NocoDB replicas. Anything above 1 requires storage.type: s3; the chart fails the render with a clear message otherwise. See Scaling.
  • siteUrl — The public base URL NocoDB puts in invitation and password-reset links, and which decides whether the auth cookie is marked secure. It must match the URL browsers actually use. Leave it empty to derive it from the workload’s canonical endpoint; set it, with the https:// scheme, when you serve NocoDB on a custom domain.
  • resources — CPU and memory bounds for the NocoDB container. The defaults suit a small production instance; raise maxCpu and maxMemory together for large imports. Upstream recommends 4 vCPU and 8 GB for a busy multi-team instance.

Super-Admin Bootstrap

By default (admin.secretName: "") NocoDB seeds no account and the first person to sign up becomes the super admin. To create the account up front instead, put the credentials in a dictionary secret and reference it by name:
The password must be at least 8 characters with an uppercase letter, a digit, and a special character. When set, the NocoDB identity is granted reveal on exactly that secret.
NocoDB re-applies these credentials on every boot. If the account’s password is later changed in the UI, the next restart silently reverts it to the value in the secret. Either leave admin.secretName empty or treat the secret as the account’s source of truth.

Attachment Storage

storage.type decides where uploaded files, images, and thumbnails are kept.
Attachments are written to a persistent volume set mounted at /usr/app/data, and survive restarts, redeploys, and upgrades under the same release name.
Local storage works only with a single replica — each replica gets its own volume, so an attachment uploaded through one replica would be missing from the others.
storage.fileUploadSizeLimit caps the size of a single attachment and is a byte count, not a size string — the default 20971520 is 20 MiB. It applies in both storage modes.
An upload larger than the limit is rejected outright, not truncated: the API returns 413 with {"message": "File too large", "error": "Payload Too Large", "statusCode": 413}. A file under the limit is stored byte-exact. Raise the value before importing large attachments.

Scaling

nocodb.replicas sets how many NocoDB replicas run. Replicas coordinate through the bundled Redis, which carries the job and event pub/sub, the shared metadata cache, and the rate limiter — all three are what make a second replica correct rather than merely present.
nocodb.replicas above 1 requires storage.type: s3. Local attachments live on per-replica volumes, so an attachment uploaded through one replica would return a 404 from another. The chart refuses to render the combination.
Measured at two replicas: a full rolling upgrade served 434 of 434 requests with HTTP 200, and abruptly killing one replica’s process produced 6 × HTTP 503 out of 289 requests inside an ~11 second window before traffic settled on the survivor. A graceful rollout is therefore seamless, while a hard replica loss costs up to about one readiness-probe period (15 seconds) of partial failures.
Live updates reach the browser over HTTP long-poll — POST /jobs/listen, backed by the Redis pub/sub — not over websockets. A stalled live update is a Redis or /jobs/listen problem.
Background jobs run inside the web process. Community Edition ships only an in-process queue, so a long import, export, or base duplication dies with the replica running it and has to be re-run. Multiple replicas buy request availability and clean rolling upgrades, not job durability.

Email

SMTP is off by default, and a default install works without it — the first visitor still creates the super-admin account and signs in with its password.
NocoDB activates its mail plugin only when host, port, and from are all set; the chart fails the render if smtp.enabled is true and any of them is missing. For an authenticated relay, create the credentials secret before installing and reference it by name:
Leave smtp.auth.secretName empty for a relay that does not require authentication. When it is set, the NocoDB identity is granted reveal on exactly that secret.
With SMTP disabled there is no way to deliver a member invitation or a password-reset mail. Configure smtp.* before inviting collaborators.

Access

  • publicAccess.enabled — Serve the UI, the API, and shared views and forms on the auto-assigned *.cpln.app HTTPS endpoint (default). Set to false for an internal-only instance: external requests are then refused at the edge with a 403, and in-GVC callers still reach it per internalAccess. With public access off, nocodb.siteUrl falls back to the internal http://{release}-nocodb.{gvc}.cpln.local:8080 address.
  • internalAccess.type — Controls which workloads can reach NocoDB over the internal network:
Firewall changes are not instantaneous. After an upgrade that flips publicAccess.enabled or internalAccess.type reports success, requests can keep hitting the old rules for roughly half a minute or more. Re-test after a pause rather than concluding the knob did not work.

Redis

  • redis.image — The Redis image to run.
  • redis.auth.password — Password for the bundled Redis, wired into NC_REDIS_URL. Change it before installing. Use only letters, digits, -, and _: the value is embedded in a URL. Authentication is required — an unauthenticated client is refused with NOAUTH Authentication required.
  • redis.resources / redis.volumeset.capacity — CPU and memory bounds and the volume size for the AOF file at /data. Redis runs with appendonly yes and reloads its data set after a restart.
Redis runs with maxmemory-policy noeviction, and this is deliberate: an evicted key would silently drop a job event. NocoDB does not tolerate losing its Redis connection — it logs an ioredis error storm and exits rather than reconnecting, and the platform restarts it. See the note about the first upgrade under Important Notes.

Database

Enable exactly one of postgres (single instance, default) or postgresHA (highly available) — see Choosing a Database Mode. In both modes, change the database password before installing (postgres.config.password / postgresHA.postgres.password); it seeds the database on first boot and cannot be changed by editing values afterwards. Use only letters, digits, -, and _ — the password is embedded in the connection URL. NocoDB connects to the single instance directly, or to the HAProxy leader endpoint in HA mode, and creates its own meta tables and one schema per base on first boot. postgres.resources / postgresHA.resources and the volumeset.capacity values (GiB, minimum 10, per replica in HA mode) size the backing store. postgresHA.replicas sets the number of Patroni replicas.

Connecting

Backing Up

Database backups are optional and disabled by default. When enabled, a scheduled job runs inside the backing PostgreSQL store and uploads to your bucket under the configured prefix — covering every base, record, view, and user, but not the attachments on the local storage volume set (use storage.type: s3 for durable attachments). Enable with postgres.backup.enabled or postgresHA.backup.enabled, matching your database mode, and complete the storage setup for your provider before installing. The values below are shown under backup.* — set them within the enabled database block.
1

Create a bucket

Create an S3 bucket. Set backup.aws.bucket and backup.aws.region to match.
2

Set up a Cloud Account

If you do not have one, create a Cloud Account for your AWS account. Set backup.aws.cloudAccountName to its name.
3

Create a bucket-scoped IAM policy

Create an IAM policy granting the required S3 actions on the bucket, and set backup.aws.policyName to its name:
In HA mode, postgresHA.backup.mode selects logical (scheduled pg_dump) or wal-g (continuous WAL archiving). The single-instance path takes a postgres.backup.schedule cron expression (default 0 2 * * *), and its postgres.backup.image tag must match the PostgreSQL major in postgres.image — change both together if you move off the default. The full per-provider walkthrough, including restores, lives in the backing postgres and postgres-highly-available template documentation.

Important Notes

  • Create the key secret before installingsecrets.name must point at an existing dictionary secret holding NC_AUTH_JWT_SECRET and NC_CONNECTION_ENCRYPT_KEY. Without it the deployment waits on a secret that does not exist and looks broken.
  • Both keys are write-once — rotating NC_AUTH_JWT_SECRET logs out every user, and changing NC_CONNECTION_ENCRYPT_KEY makes the stored credentials of external data sources undecryptable. Back both values up outside Control Plane.
  • Sign up immediately after install — signup is open by default, so on a public endpoint the first visitor to sign up becomes the super admin. Then turn on invite-only in Team & Settings; it is an in-app setting, not a template value.
  • The first helm upgrade after an install briefly restarts the bundled Redis, even when nothing about Redis changed, and NocoDB exits rather than reconnecting. At replicas: 1 that is a short outage on a routine config change — the endpoint returns 503 no healthy upstream for about a minute. At replicas: 2 it was not user-visible. Later upgrades of the same release do not restart Redis.
  • nocodb.replicas above 1 requires storage.type: s3 — local attachments are per-replica and would 404 across replicas; the chart refuses to render the combination.
  • A hard replica loss is not free — a rolling upgrade at two replicas served 434 of 434 requests successfully, but killing a replica outright produced 6 failed requests out of 289 across an ~11 second window. The readiness probe runs every 15 seconds, so budget up to one probe period of partial 503s on abrupt replica death.
  • Background jobs are in-process — a long import, export, or base duplication does not survive the replica running it and must be re-run.
  • Live updates use HTTP long-poll, not websocketsPOST /jobs/listen backed by Redis pub/sub is the delivery path.
  • storage.fileUploadSizeLimit is a byte count — the default 20971520 is 20 MiB. An over-limit upload is rejected with 413 and File too large, not truncated.
  • AWS S3 is keyless only — use a cloud account plus a bucket-scoped IAM policy. Static keys are accepted only when storage.s3.endpoint points at an S3-compatible server.
  • admin.secretName re-applies on every boot — a password changed in the UI is reverted at the next restart. Leave it empty or treat the secret as the source of truth.
  • The single-instance and HA database paths run different PostgreSQL majors — 18 and 17 respectively. Choose before you have data; switching is a dump and restore.
  • Change postgres.config.password (or postgresHA.postgres.password) and redis.auth.password before installing — both seed their component on first boot, and both are embedded in connection URLs, so use only letters, digits, -, and _.
  • Set nocodb.siteUrl when NocoDB sits behind a custom domain, with the scheme (https://data.example.com). It drives invitation and password-reset links and the auth cookie’s secure flag, so a mismatch with the URL browsers use breaks both.
  • Firewall changes take effect after a delay — flipping publicAccess.enabled or internalAccess.type can take half a minute or more to be enforced after the upgrade reports success.
  • With SMTP off, invitations and password resets cannot be delivered — configure smtp.* before inviting collaborators.
  • Data survives restarts and upgrades; uninstalling deletes it — bases live in the database volume set and local attachments in the storage volume set, and both go with the release. Your prerequisite key secret is yours and survives an uninstall.
  • SSO/SAML/OIDC, audit logs, and row-level security are Enterprise features — they ship in the same image but require a purchased licence key that this template never sets.
  • NocoDB Community Edition is fair-code — the Sustainable Use License permits self-hosting for your own use; offering NocoDB as a hosted service to others requires a commercial licence.

External References

NocoDB Documentation

Official NocoDB product documentation

Self-Hosting Guide

Deployment, upgrades, and operational guidance

Environment Variables

Every setting the NocoDB server reads from its environment

Data APIs

REST API reference for reading and writing records

NocoDB on GitHub

Source code and release notes

NocoDB Template

View the source files, default values, and chart definition