> ## Documentation Index
> Fetch the complete documentation index at: https://astron-bb4261fd.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# z3rno-helm

> Helm chart that deploys the full Z3rno stack on Kubernetes: server, Celery worker, beat scheduler, audit listener, Valkey, and optional bundled Postgres via CloudNativePG.

## Overview

`z3rno-helm` is the Helm chart that runs Z3rno on Kubernetes. The base chart renders four workload kinds:

| Workload                   | Default    | Notes                                                         |
| -------------------------- | ---------- | ------------------------------------------------------------- |
| `Deployment/z3rno-server`  | 2 replicas | The FastAPI application.                                      |
| `Deployment/z3rno-worker`  | 1 replica  | Celery worker.                                                |
| `Deployment/z3rno-beat`    | 1 replica  | Celery beat scheduler. **Singleton** — do not scale beyond 1. |
| `StatefulSet/z3rno-valkey` | 1 replica  | Bundled Valkey (Celery broker + rate-limit store).            |

Five **opt-in** blocks layer additional capability on top of the base. Each is `enabled: false` by default and back-compat — pre-flag deploys stay byte-identical.

| Opt-in                               | Flag                                                                               | Adds                                                                                                                                                 | Shipped  |
| ------------------------------------ | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| Bundled Postgres (CNPG subchart)     | `z3rno-postgres.enabled`                                                           | A `postgresql.cnpg.io/v1` Cluster CR running the `z3rno-postgres:17` image (Postgres 17 + pgvector + AGE + pg\_cron + pgaudit + pgcrypto).           | v0.19.7  |
| Observability (Prometheus + Grafana) | `observability.prometheusRules.enabled` / `observability.grafanaDashboard.enabled` | 4 SLO recording rules + 4 alerts + a stat/timeseries dashboard.                                                                                      | v0.18.0  |
| Multi-region topology                | `multiRegion.enabled`                                                              | `z3rno.region` label, zonal `topologySpreadConstraints`, optional `DATABASE_READ_URL` in the secret.                                                 | v0.17.0  |
| Inline image-pull secret             | `imagePullSecret.create`                                                           | Renders a `dockerconfigjson` Secret for private GHCR.                                                                                                | v0.19.10 |
| NOTIFY/LISTEN audit drain            | `auditListener.enabled`                                                            | A dedicated singleton `Deployment/z3rno-audit-listener` that opens `LISTEN z3rno_audit_pending` and fires `z3rno.audit_drain` on every notification. | v0.20.2  |

**Current chart version:** `0.6.0` (appVersion `0.20.0`).

## Install

The chart currently ships from source; an OCI / repo publish lands in a future release.

```bash theme={null}
git clone https://github.com/the-ai-project-co/z3rno-helm
cd z3rno-helm
helm install z3rno ./charts/z3rno \
  --namespace z3rno --create-namespace \
  --set externalDatabase.enabled=true \
  --set externalDatabase.host=YOUR_DB_HOST \
  --set secrets.databaseUrl='postgresql+asyncpg://z3rno:PASSWORD@YOUR_DB_HOST:5432/z3rno' \
  --set secrets.openaiApiKey=sk-your-openai-key
```

For a one-command local-cluster smoke (e.g. `kind`) with bundled Postgres, see the [Self-hosting / Kubernetes](/self-hosting/kubernetes) guide.

## Quick start (production shape)

```bash theme={null}
helm install z3rno ./charts/z3rno -n z3rno --create-namespace -f values-production.yaml
```

A minimal `values-production.yaml`:

```yaml theme={null}
server:
  image:
    repository: ghcr.io/safayavatsal/z3rno-server      # public mirror; OK for prod
    tag: "0.20.0"
  replicas: 3

externalDatabase:
  enabled: true
  host: "z3rno-db.abc123.us-east-1.rds.amazonaws.com"
  existingSecret: "z3rno-db-credentials"  # must have key 'password'

secrets:
  databaseUrl: "postgresql+asyncpg://z3rno:PASSWORD@z3rno-db.abc123...:5432/z3rno"
  openaiApiKey: "sk-..."
  z3rnoApiKey: "z3rno_sk_prod_..."        # rotate from the dev default

ingress:
  enabled: true
  className: nginx
  hosts:
    - host: api.example.com
      paths:
        - path: /
          pathType: Prefix

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70

# Recommended pairing: live audit drain via NOTIFY/LISTEN
auditListener:
  enabled: true
beat:
  audit:
    drainIntervalSeconds: "60.0"          # bump up; listener handles wake-up
```

## values.yaml reference

The full reference shape, organized by block:

```yaml theme={null}
# Server
server:
  image:
    repository: ghcr.io/safayavatsal/z3rno-server   # public mirror default
    tag: latest
    pullPolicy: IfNotPresent
  replicas: 2
  port: 8000
  resources:
    requests: { memory: 256Mi, cpu: 250m }
    limits:   { memory: 512Mi, cpu: 500m }

# Celery worker
worker:
  enabled: true
  replicas: 1
  command: "celery -A z3rno_server.workers.celery_app worker --loglevel=info"

# Celery beat (singleton)
beat:
  enabled: true
  replicas: 1
  command: "celery -A z3rno_server.workers.celery_app beat --loglevel=info"
  audit:
    drainIntervalSeconds: "1.0"           # bump to 60.0 when auditListener.enabled
    drainBatchSize: "500"
    maxOrgsPerTick: "100"

# Bundled Valkey
valkey:
  enabled: true                            # set false + use externalRedis for prod
  image: { repository: valkey/valkey, tag: "8" }
  port: 6379
  persistence:
    enabled: true
    size: 1Gi
    storageClass: ""

# External Postgres (recommended for prod)
externalDatabase:
  enabled: false
  host: ""
  port: 5432
  name: "z3rno"
  user: "z3rno"
  existingSecret: ""
  secretKey: "password"

# External Redis (replaces bundled Valkey)
externalRedis:
  enabled: false
  host: ""
  port: 6379
  existingSecret: ""
  secretKey: "redis-password"

# Secrets — set existingSecret to source from your secret manager
secrets:
  databaseUrl: ""
  redisUrl: ""
  openaiApiKey: ""
  z3rnoApiKey: "z3rno_sk_test_localdev"   # rotate for non-localhost deploys
  existingSecret: ""

# Ingress
ingress:
  enabled: false
  className: ""
  annotations: {}
  hosts:
    - host: z3rno.local
      paths: [{ path: /, pathType: Prefix }]
  tls: []

# Horizontal Pod Autoscaler (targets server)
autoscaling:
  enabled: false
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70
  targetMemoryUtilizationPercentage: 80

# Pod Disruption Budget (targets server)
podDisruptionBudget:
  enabled: false
  minAvailable: 1

# Free-form env injected into server / worker / beat pods
env: {}
```

### Opt-in blocks

```yaml theme={null}
# v0.19.7 — bundled Postgres via CloudNativePG subchart.
# When true, renders a postgresql.cnpg.io/v1 Cluster CR running
# z3rno-postgres:17 (Postgres 17 + pgvector + AGE + pg_cron +
# pgaudit + pgcrypto). Auto-emits <release>-z3rno-rw / -ro services.
# Requires the CNPG operator pre-installed in the cluster.
z3rno-postgres:
  enabled: false

# v0.18.0 — Prometheus rules + Grafana dashboard.
observability:
  prometheusRules:
    enabled: false                        # needs prometheus-operator CR
    extraLabels: {}
  grafanaDashboard:
    enabled: false                        # needs Grafana sidecar
    extraLabels: {}

# v0.17.0 — multi-region topology.
multiRegion:
  enabled: false
  region: ""                              # e.g. "us-east-1"
  zones: []                               # zonal topology spread
  readDatabaseUrl: ""                     # populates DATABASE_READ_URL
  secondaryRegions: []                    # documentation field

# v0.19.10 — inline ghcr.io pull secret (alt: pre-create + use imagePullSecrets).
imagePullSecret:
  create: false
  registry: "ghcr.io"
  username: ""
  password: ""                            # GH PAT with read:packages
  dockerconfigjson: ""                    # OR pre-built base64 dockerconfigjson

# v0.20.2 — NOTIFY/LISTEN audit drain listener.
# When true, deploys a singleton z3rno-audit-listener pod that opens
# LISTEN z3rno_audit_pending and fires z3rno.audit_drain on every
# notification (~50 ms wake instead of waiting for beat). The beat-
# driven poll stays as a fallback; bump beat.audit.drainIntervalSeconds
# to 60.0 when listener is enabled.
auditListener:
  enabled: false
```

## Using an external database

For production, point at a managed PostgreSQL (RDS, Cloud SQL, Neon, or self-managed):

```yaml theme={null}
externalDatabase:
  enabled: true
  host: "z3rno-db.abc123.us-east-1.rds.amazonaws.com"
  port: 5432
  name: "z3rno"
  user: "z3rno"
  existingSecret: "z3rno-db-credentials"   # must contain key 'password'
```

<Warning>
  Your external PostgreSQL must have **pgvector, Apache AGE, pg\_cron, pgaudit, and pgcrypto** installed. The reference image `ghcr.io/the-ai-project-co/z3rno-postgres:17` ships all five pre-compiled — use it directly if you can, or replicate the extension set on your managed instance. The `z3rno-postgres` subchart (set `z3rno-postgres.enabled=true`) renders a CNPG-managed cluster of this image for you.
</Warning>

## Upgrading

```bash theme={null}
git pull              # in the z3rno-helm checkout
helm upgrade z3rno ./charts/z3rno -n z3rno -f values.yaml
```

Database migrations run automatically via an init container on the server pods. The chart applies them with `alembic upgrade head` against the configured `DATABASE_URL`. Pre-flight check:

```bash theme={null}
kubectl get pods -n z3rno
kubectl logs -n z3rno -l app.kubernetes.io/component=server -c migrate
```

## Uninstalling

```bash theme={null}
helm uninstall z3rno --namespace z3rno
# PVCs are retained — manually delete to wipe Valkey + (if bundled) Postgres data
kubectl delete pvc -l app.kubernetes.io/instance=z3rno -n z3rno
```

## Resource recommendations

| Scale                    | Server CPU/mem | Worker CPU/mem | Postgres CPU/mem | Postgres storage |
| ------------------------ | -------------- | -------------- | ---------------- | ---------------- |
| Dev / test               | 250m / 512Mi   | 250m / 256Mi   | 500m / 1Gi       | 10Gi             |
| Small (\< 100K memories) | 500m / 1Gi     | 500m / 512Mi   | 1 / 2Gi          | 50Gi             |
| Medium (\< 1M memories)  | 1 / 2Gi        | 1 / 1Gi        | 2 / 8Gi          | 200Gi            |
| Large (> 1M memories)    | 2 / 4Gi        | 2 / 2Gi        | 4 / 16Gi+        | 500Gi+           |

For Phase 3 cloud-cluster validation targets (10K concurrent users across 200 orgs) see [`status/PHASE-3-DEFERRED-TESTS.md`](https://github.com/the-ai-project-co/z3rno-process-docs/blob/main/improvements/status/PHASE-3-DEFERRED-TESTS.md) in z3rno-process-docs.

## Reference

* **Source:** [github.com/the-ai-project-co/z3rno-helm](https://github.com/the-ai-project-co/z3rno-helm)
* **Server image:** `ghcr.io/safayavatsal/z3rno-server:0.20.0` (public mirror; default in `values.yaml`)
* **Postgres image:** `ghcr.io/the-ai-project-co/z3rno-postgres:17` (pre-compiled with all 5 required extensions)
* **Server reference:** [Components → z3rno-server](/components/server)
* **Per-release detail:** [`changelogs/`](https://github.com/the-ai-project-co/z3rno-process-docs/tree/main/improvements/changelogs)
