# Install

> Part of the NocoDB documentation (Self-hosting > Installation > Kubernetes). Index of all pages: https://nocodb.com/llms.txt. Any docs page is available as Markdown by adding `.md` to its URL.

URL: https://nocodb.com/docs/self-hosting/installation/kubernetes/install
Last updated: 2026-10-03

Install NocoDB for production on Kubernetes with the official Helm chart.

This guide installs NocoDB for production with external PostgreSQL and Redis. After install, you
connect object storage for attachments in the admin panel.

## 1. Prepare your datastores

1. Set up a PostgreSQL database and a Redis instance. NocoDB runs its own schema migrations at
   startup, so the database user needs DDL privileges on its schema.
2. Enable TLS on PostgreSQL and Redis where possible.
3. Set up an S3-compatible bucket for attachments. You connect it in the NocoDB admin panel
   after install (refer to [step 5](#5-configure-attachment-storage)), not through the chart. Thus, no S3
   credentials go into your Kubernetes Secret.

## 2. Create the secret

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

| Key            | Purpose        | Example                                                   |
| -------------- | -------------- | --------------------------------------------------------- |
| `DATABASE_URL` | PostgreSQL URL | `postgresql://user:pass@host:5432/nocodb?sslmode=require` |
| `NC_REDIS_URL` | Redis URL      | `rediss://:pass@host:6379`                                |

```bash
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'
```

<Callout type="tip">
  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.
</Callout>

## 3. Install the chart

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

This is a minimal production `values.yaml`:

```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]
```

Make sure that the rollout is successful:

```bash
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

1. Set `ingress.enabled: true`.
2. Set an `ingress.className`.
3. Add a cert-manager `cluster-issuer` annotation, or supply your own TLS secret under `ingress.tls`.

The chart gets `NC_SITE_URL` from the first ingress host automatically. It uses `https` when TLS is
configured. To use a different value, set `nocodb.publicUrl`.

## 5. Configure attachment storage

NocoDB stores uploaded files in object storage. You configure the storage in the app, not in the chart.
When the app is available:

1. Sign in as a super admin.
2. Open the **App Store**.
3. Set up an S3-compatible **Storage** plugin with your bucket and credentials. Supported
   providers include AWS S3, MinIO, Google Cloud Storage and others.

NocoDB saves the setting in the metadata database, so all app and worker replicas use it
automatically. For the full list of supported providers, refer to
[App Store integrations](/docs/product/account-settings/oss-specific-details#app-store).

<Callout type="warn">
  Configure object storage before users upload files. Until you do, attachments are written to local
  pod storage and are not shared across replicas.
</Callout>

## 6. High availability

The app and the worker scale independently:

* **App**: scale freely. Run `replicaCount: 2`+ (requires Redis), or enable the HPA with
  `autoscaling.enabled: true`. App pods are stateless. Redis sends WebSocket events to all replicas,
  so you do not need sticky sessions.
* **Worker**: for stability, use a fixed `worker.replicaCount` of 2 or more (refer to Background workers below).
* Enable a PodDisruptionBudget with `pdb.create: true`. It covers the app and the worker.
* The chart has a soft pod anti-affinity by default (`podAntiAffinityPreset: soft`).

## 7. Background workers

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

Run a **fixed `worker.replicaCount` of 2 or more**. Do not autoscale workers. Workers run
asynchronous jobs. A scale-down or a rolling update stops a pod, and that pod can be in the middle of a job.

At shutdown, NocoDB tries to finish running jobs within `worker.terminationGracePeriodSeconds`
(default 120s). Set it to a value above the duration of your longest job. If a worker stops before it
finishes, Bull runs the job again on another worker through stalled-job recovery. Thus, **jobs should be
idempotent**.

Worker autoscaling is available (`worker.autoscaling.enabled: true`, with a minimum of 2 replicas). It is
off by default. Enable it only if your jobs are short and idempotent, and you have tuned the grace period.
To tune throughput, use `worker.replicaCount` and `worker.concurrency`.

## 8. SSO

1. Set `sso.oidc.enabled: true` (or `sso.saml.enabled: true`).
2. Supply the provider client secrets through `extraEnvVars` that refer to your secret.

For the variables, refer to
[environment variables](/docs/self-hosting/environment-variables).

## 9. Observability

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

## 10. Additional configuration

For settings that the chart does not model directly, use `extraEnvVars`, `extraVolumes`/`extraVolumeMounts`
and `extraDeploy`. For PostgreSQL with a private CA, mount the CA through `extraVolumes` and set
`NC_DB_JSON_FILE` through `extraEnvVars`.

## Production checklist

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

## Parameters reference

For the full parameter table, refer to the chart `README.md`.

---

## Related pages

- [Kubernetes](https://nocodb.com/docs/self-hosting/installation/kubernetes.md): Deploy NocoDB on Kubernetes with the official Helm chart for production and high-availability setups.
- [Upgrade & Backup](https://nocodb.com/docs/self-hosting/installation/kubernetes/upgrade.md): Upgrade, roll back and back up a NocoDB Helm deployment on Kubernetes.
