Install

Production installation of NocoDB on Kubernetes with the official Helm chart.

This guide installs NocoDB for production against external PostgreSQL and Redis, with object storage for attachments connected from the admin panel after install.

1. Prepare your datastores

Provision a PostgreSQL database and a Redis instance. NocoDB runs its own schema migrations on startup, so the database user needs DDL privileges on its schema. Enable TLS on PostgreSQL and Redis where possible.

Also provision an S3-compatible bucket for attachments. You connect it from the NocoDB admin panel after install (see step 5), not through the chart, so no S3 credentials go into your Kubernetes Secret.

2. Create the secret

Create one Kubernetes Secret holding your connection strings and credentials. The chart reads these keys:

KeyPurposeExample
DATABASE_URLPostgreSQL URLpostgresql://user:pass@host:5432/nocodb?sslmode=require
NC_REDIS_URLRedis URLrediss://:pass@host:6379
kubectl create namespace nocodb
kubectl -n nocodb create secret generic nocodb-secrets \
  --from-literal=DATABASE_URL='postgresql://user:pass@db.internal:5432/nocodb?sslmode=require' \
  --from-literal=NC_REDIS_URL='rediss://:pass@redis.internal:6379'

This same pattern works with the External Secrets Operator or Sealed Secrets: have your tool create the Secret, then point the chart at it. The JWT secret and datasource encryption key are auto-generated and preserved across upgrades if you do not provide them.

3. Install the chart

helm install nocodb oci://ghcr.io/nocodb/charts/nocodb --version 1.0.0 \
  -n nocodb --create-namespace -f values.yaml

A minimal production values.yaml:

replicaCount: 2
worker:
  enabled: true
  replicaCount: 2
externalDatabase:
  existingSecret: nocodb-secrets
externalRedis:
  existingSecret: nocodb-secrets
ingress:
  enabled: true
  className: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: nocodb.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: nocodb-tls
      hosts: [nocodb.example.com]

Verify the rollout:

kubectl -n nocodb rollout status deploy/nocodb
kubectl -n nocodb exec deploy/nocodb -- wget -qO- http://localhost:8080/api/v1/health

4. Ingress and TLS

Set ingress.enabled: true, an ingress.className, and a cert-manager cluster-issuer annotation (or supply your own TLS secret under ingress.tls). The chart derives NC_SITE_URL from the first ingress host automatically, using https when TLS is configured; override it with nocodb.publicUrl if needed.

5. Configure attachment storage

NocoDB stores uploaded files in object storage configured from the app, not the chart. Once the app is reachable, sign in as a super admin, open the App Store, and set up an S3-compatible Storage plugin (AWS S3, MinIO, Google Cloud Storage, and others are supported) with your bucket and credentials.

The setting is saved in the metadata database, so every app and worker replica picks it up automatically. See App Store integrations for the full list of supported providers.

Configure object storage before users upload files. Until you do, attachments are written to local pod storage and are not shared across replicas.

6. High availability

The app and worker scale independently:

  • App: scale freely. Run replicaCount: 2+ (requires Redis) or enable the HPA with autoscaling.enabled: true. App pods are stateless; WebSocket events fan out across replicas through Redis, so no sticky sessions are needed.
  • Worker: prefer a fixed worker.replicaCount of 2 or more for stability (see Background workers below).
  • Enable a PodDisruptionBudget with pdb.create: true (covers both the app and the worker).
  • The chart ships a soft pod anti-affinity by default (podAntiAffinityPreset: soft).

7. Background workers

Workers process the shared Bull job queue (imports, thumbnails, migrations) and require Redis.

Run a fixed worker.replicaCount of 2 or more rather than autoscaling them. Workers run asynchronous jobs, so scaling down (or a rolling update) terminates a pod that may be mid-job. On shutdown NocoDB tries to finish in-flight jobs within worker.terminationGracePeriodSeconds (default 120s); raise it above the duration of your longest job. If a worker is killed before it finishes, Bull re-runs the job on another worker through stalled-job recovery, so jobs should be idempotent.

Worker autoscaling is available (worker.autoscaling.enabled: true, floored at 2 replicas) but is opt-in: enable it only if your jobs are short and idempotent and you have tuned the grace period. Tune throughput with worker.replicaCount and worker.concurrency.

8. SSO

Set sso.oidc.enabled: true (or sso.saml.enabled: true) and provide provider client secrets via extraEnvVars referencing your secret. See environment variables.

9. Observability

NocoDB does not expose a Prometheus metrics endpoint. Collect container logs with your cluster logging stack and, optionally, set monitoring.sentry.enabled: true for error reporting. Pod and cluster metrics come from the standard kube-state-metrics / cAdvisor stack.

10. Additional configuration

Use extraEnvVars, extraVolumes/extraVolumeMounts, and extraDeploy for anything the chart does not model directly. For PostgreSQL with a private CA, mount the CA via extraVolumes and set NC_DB_JSON_FILE through extraEnvVars.

Production checklist

  • External PostgreSQL and Redis configured; attachment storage set up in the App Store
  • All credentials via existingSecret (no inline secrets)
  • resources reviewed (defaults request 1 vCPU and 2 GiB memory per pod; 1 GiB memory minimum)
  • pdb.create: true and anti-affinity in place
  • autoscaling.enabled: true (or a fixed replicaCount ≥ 2)
  • TLS configured via ingress
  • Image tag pinned (defaults to the chart's appVersion)
  • Database backups configured
  • Readiness verified via /api/v1/health

Parameters reference

See the chart README.md for the full parameter table.