Skip to main content

Prerequisites

  • kubectl configured against a running Kubernetes cluster
  • Helm 3.x
  • Sufficient cluster capacity — see resource recommendations below

Helm chart overview

The Onyx Helm chart is located at deployment/helm/charts/onyx in the repository. It bundles the following subcharts as optional dependencies (all enabled by default):
SubchartVersionPurpose
cloudnative-pg0.26.0PostgreSQL cluster operator
vespa0.2.25Vector/keyword search engine
opensearch3.4.0Full-text search index
ingress-nginx4.13.3Reverse proxy / load balancer
redis0.16.6Celery broker and cache
minio5.4.0S3-compatible file store
code-interpreter0.3.1Sandboxed Python execution
Chart version: 0.4.38 — App version: latest

Installation

1

Add the Helm repository dependencies

The chart depends on several external Helm repositories. Run helm dependency update from the chart directory to fetch them:
cd deployment/helm/charts/onyx
helm dependency update .
2

Create a namespace

kubectl create namespace onyx
3

Set the required OpenSearch admin password

The bundled OpenSearch chart requires an admin password to be set on first install. You must provide it before the cluster initialises — changing it later will not rotate the OpenSearch password.
# The password must contain uppercase, lowercase, a digit, and a special character (min 8 chars).
helm install onyx ./deployment/helm/charts/onyx \
  --namespace onyx \
  --set auth.opensearch.values.opensearch_admin_password='YourStrongPassword1!'
4

Customise values (recommended)

Copy values.yaml to a local override file and edit it. Then install using both files:
helm install onyx ./deployment/helm/charts/onyx \
  --namespace onyx \
  -f my-values.yaml
5

Verify the rollout

kubectl -n onyx get pods
kubectl -n onyx rollout status deployment/onyx-api

Key values

The sections below cover the most commonly changed values. For the full reference, read values.yaml in the chart directory.

Global settings

global:
  version: "latest"        # Image tag for all Onyx components
  pullPolicy: "IfNotPresent"

configMap:
  AUTH_TYPE: "basic"       # basic | google_oauth | oidc | saml
  WEB_DOMAIN: "https://onyx.example.com"
  DOMAIN: "onyx.example.com"

Authentication secrets

The chart manages Kubernetes Secrets for all credentials. Provide values before first install:
auth:
  postgresql:
    values:
      username: "postgres"
      password: "change-me"       # Postgres superuser password

  redis:
    values:
      redis_password: "change-me"

  objectstorage:
    values:
      s3_aws_access_key_id: "minioadmin"
      s3_aws_secret_access_key: "change-me"
      rootUser: "minioadmin"
      rootPassword: "change-me"

  opensearch:
    values:
      opensearch_admin_username: "admin"
      opensearch_admin_password: "YourStrongPassword1!"

  userauth:
    enabled: true
    values:
      user_auth_secret: ""        # Generate with: openssl rand -hex 32
Use existingSecret fields to reference pre-existing Kubernetes Secrets instead of embedding credentials in values.yaml. This is required for GitOps workflows.

Disabling vector DB (lite mode)

For a minimal deployment without connectors or RAG search:
vectorDB:
  enabled: false

vespa:
  enabled: false

redis:
  enabled: false

configMap:
  CACHE_BACKEND: "postgres"
  AUTH_BACKEND: "postgres"
  FILE_STORE_BACKEND: "postgres"
Alternatively, use the bundled values-lite.yaml:
helm install onyx ./deployment/helm/charts/onyx \
  --namespace onyx \
  -f ./deployment/helm/charts/onyx/values-lite.yaml

Resource recommendations

The values below are the chart defaults. Tune them for your workload — Vespa in particular benefits from additional memory when indexing at scale.
ComponentCPU requestCPU limitMemory requestMemory limit
api (API server)500m1000m1 Gi3 Gi
webserver200m1000m512 Mi1 Gi
vespa4000m8000m8000 Mi32000 Mi
opensearch2000m4000m4 Gi8 Gi
inferenceCapability2000m4000m3 Gi10 Gi
indexCapability4000m6000m3 Gi6 Gi
celery_worker_docprocessing500m1000m2 Gi12 Gi
celery_worker_docfetching500m1000m2 Gi16 Gi
celery_worker_primary500m1000m2 Gi4 Gi
celery_worker_light250m2000m512 Mi4 Gi
celery_worker_heavy500m1000m512 Mi2 Gi
celery_beat500m1000m512 Mi1 Gi
At large indexing scale, consider hosting Vespa externally (e.g., Vespa Cloud) and pointing VESPA_HOST at it. Disable the in-cluster vespa subchart with vespa.enabled: false.

PersistentVolumeClaim requirements

The chart creates PVCs for the following stateful services:
ServicePVC nameDefault sizeAccess mode
PostgreSQL (CloudNativePG)Managed by operator10 GiReadWriteOnce
Vespavespa-storage-da-vespa-030 GiReadWriteOnce
OpenSearchdata-onyx-opensearch-master-030 GiReadWriteOnce
MinIOManaged by subchart30 GiReadWriteOnce
RedisManaged by subchart1 GiReadWriteOnce
Set storageClassName in each section of values.yaml to match the StorageClass available in your cluster:
postgresql:
  cluster:
    storage:
      storageClass: "gp3"
      size: 10Gi

vespa:
  volumeClaimTemplates:
    - metadata:
        name: vespa-storage
      spec:
        storageClassName: "gp3"
        resources:
          requests:
            storage: 30Gi

opensearch:
  persistence:
    storageClass: "gp3"
    size: 30Gi

minio:
  persistence:
    storageClass: "gp3"
    size: 30Gi
Vespa leaves behind its PVC when the chart is uninstalled. Delete it manually if you are completely removing Onyx:
kubectl -n onyx delete pvc vespa-storage-da-vespa-0

Ingress configuration

The chart uses ingress-nginx (aliased as nginx) as the in-cluster ingress controller. It is enabled by default and exposes a LoadBalancer service on port 80. To use an existing ingress controller instead, disable the bundled nginx and configure the ingress section:
nginx:
  enabled: false

ingress:
  enabled: true
  className: "nginx"        # or "traefik", "alb", etc.
  api:
    host: onyx.example.com
  webserver:
    host: onyx.example.com
For HTTPS with Let’s Encrypt (cert-manager):
letsencrypt:
  enabled: true
  email: "[email protected]"

Autoscaling

The chart supports both Kubernetes HPA and KEDA ScaledObjects. HPA is the default.
autoscaling:
  engine: hpa    # or "keda" (requires the KEDA operator pre-installed)

# Per-component autoscaling example:
api:
  autoscaling:
    enabled: true
    minReplicas: 2
    maxReplicas: 10
    targetCPUUtilizationPercentage: 70
To use KEDA, install the KEDA operator separately before changing autoscaling.engine. The chart no longer bundles KEDA as a dependency.

Running as non-root

By default, some Onyx containers run as root. To enforce non-root execution:
# Apply to: celery_shared, api, webserver, indexCapability, inferenceCapability
securityContext:
  runAsNonRoot: true
  runAsUser: 1001

# Vespa requires a specific UID
vespa:
  podSecurityContext:
    fsGroup: 1000
  securityContext:
    privileged: false
    runAsUser: 1000

Common Helm commands

# Install
helm install onyx ./deployment/helm/charts/onyx --namespace onyx -f my-values.yaml

# Upgrade (applies value changes and image updates)
helm upgrade onyx ./deployment/helm/charts/onyx --namespace onyx -f my-values.yaml

# Check rendered templates without installing
helm template onyx ./deployment/helm/charts/onyx -f my-values.yaml

# Uninstall (does not delete PVCs)
helm uninstall onyx --namespace onyx

# Port-forward the nginx service for local testing
kubectl -n onyx port-forward service/onyx-nginx 8080:80

Enterprise Edition

Multi-tenancy support is an Enterprise Edition feature. Enable it in values.yaml:
configMap:
  ENABLE_PAID_ENTERPRISE_EDITION_FEATURES: "true"
Contact the Onyx team for a license key before enabling Enterprise features.

Build docs developers (and LLMs) love