Installing Helix on Kubernetes with Helm

This page describes how to install Helix on Kubernetes.

Requirements

  • Control Plane is the Helix API, web interface, and postgres database and requires:

  • Inference Provider requires ONE OF:

    • An NVIDIA GPU if you want to use private Helix Runners (example), or
    • Ollama running locally on macOS, Linux or Windows (example), or
    • An OpenAI-compatible API provider, such as TogetherAI (example) - we like TogetherAI because you can run the same open source models via their API that you can run locally using Helix GPU Runners, but you can use any OpenAI-compatible API (e.g. vLLM, Azure OpenAI, Gemini etc)
  • Private Helix Runners require:

    • As much system memory as you have GPU memory
    • Min 8GB GPU for small models (Llama3-8B, Phi3-Mini), 24GB for Mixtral/SDXL, 40GB for Llama3-70B
    • Min 24GB GPU for fine-tuning (text or image)
    • Recommend 2x24GB GPUs for e.g. text & image inference in parallel
    • NVIDIA 3090s, A6000s are typically good price/performance
    • 150GB+ of free disk space
    • A fast internet connection (small runner image is 23GB)
The Helm chart does NOT work on Docker Desktop Kubernetes. Please use kind, minikube or an official Kubernetes cluster.

Deploying the Control Plane

This section details how to install the Helix control plane.

There is an example script in the repository that shows you an example of deploying the control plane to a kind cluster.

1. Install Keycloak

Helix uses Keycloak for authentication. If you have one already, you can skip this step. Otherwise, to install one through Helm (chart info, repo). This step installs our Keycloak image with the Helix theme installed.

For example:

HELIX_VERSION=$(curl -s https://get.helixml.tech/latest.txt)
helm upgrade --install keycloak oci://registry-1.docker.io/bitnamicharts/keycloak \
  --version "24.3.1" \
  --set global.security.allowInsecureImages=true \
  --set image.registry=registry.helixml.tech \
  --set image.repository=helix/keycloak-bitnami \
  --set image.tag="${HELIX_VERSION}" \
  --set auth.adminUser=admin \
  --set auth.adminPassword=oh-hallo-insecure-password \
  --set httpRelativePath="/auth/"

Note: Helix includes a custom Keycloak image with the Helix theme pre-installed. Helix will also work with a standard Keycloak install.

Note the pinned version of the chart and the image tag. These are versions that we have tested and are known to work. Newer versions may work, but we have not tested them. Raise an issue if you have any issues.

You do not need to expose a service to access Keycloak from outside the cluster - it is used as an internal implementation detail of Helix (and Helix manages the helix Keycloak realm via admin access).

Wait until the Keycloak is running:

kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
keycloak-0              0/1     Running   0          61s
keycloak-postgresql-0   1/1     Running   0          61s

Both pods should turn 1/1 running.

Using an External PostgreSQL Database

Keycloak uses PostgreSQL to persist state. If you want to reuse a pre-existing PostgreSQL cluster, please add the following settings:

  --set postgresql.enabled=false \
  --set externalDatabase.existingSecret=helix-external-postgres-app \
  --set externalDatabase.existingSecretHostKey=host \
  --set externalDatabase.existingSecretPortKey=port \
  --set externalDatabase.existingSecretUserKey=user \
  --set externalDatabase.existingSecretDatabaseKey=dbname \
  --set externalDatabase.existingSecretPasswordKey=password \

This assumes that the helix-external-postgres-app exists with the expected secrets.

2. Install the Helm Repository

helm repo add helix https://charts.helixml.tech 
helm repo update

3. Apply the Chart

Use the license key from the license manager and create a secret with the contents:

kubectl create \
    secret generic helix-license \
    --from-literal=license="<base64 encoded secret contents here>"

Copy the values-example.yaml from the repository to configure the Helix control plane. You can look at the configuration documentation to learn more about what they do.

curl -o values-example.yaml https://raw.githubusercontent.com/helixml/helix/main/charts/helix-controlplane/values-example.yaml

You must edit the provider configuration in this file so that Helix can run. Specifying a remote provider (e.g. openai or togetherai) is the easiest, but you must provide API keys to do that. A helix provider ensures local operation but then you must also add a runner.

Now you’re ready to install the control plane helm chart with the latest images.

export LATEST_RELEASE=$(curl -s https://get.helixml.tech/latest.txt)

helm upgrade --install my-helix-controlplane helix/helix-controlplane \
  -f values-example.yaml \
  --set image.tag="${LATEST_RELEASE}"

Ensure all the pods start. If they do not inspect the logs.

Once they are all running, access the control plane via port-forwarding (default) or according to your configuration, for example:

kubectl port-forward svc/helix-helix-controlplane 8080:80

You can configure the Kubernetes deployment by overriding the settings in the values.yaml.

Database Configuration

Helix requires PostgreSQL for application data and optionally PostgreSQL with the PGVector extension for RAG (Retrieval-Augmented Generation) functionality. You can use vanilla PostgreSQL for the main database and PostgreSQL with the PGVector extension for vectors. Both configurations support bundled deployment or external connection with comprehensive secret support.

PostgreSQL Configuration

Bundled PostgreSQL (default):

postgresql:
  enabled: true
  auth:
    username: helix
    password: "secure-password"
    database: helix
    # Optional: Use existing secret
    # existingSecret: "postgresql-auth-secret"
    # usernameKey: "username"      # defaults to "username"
    # passwordKey: "password"      # defaults to "password"
    # databaseKey: "database"      # defaults to "database"

External PostgreSQL:

postgresql:
  enabled: false
  external:
    host: "my-postgres.example.com"
    port: 5432
    user: "helix"
    password: "secure-password"
    database: "helix"
    # Optional: Use existing secret
    # existingSecret: "postgresql-external-secret"
    # existingSecretHostKey: "host"
    # existingSecretUserKey: "user"
    # existingSecretPasswordKey: "password"
    # existingSecretDatabaseKey: "database"
PostgreSQL with PGVector Extension Configuration (for RAG)

Bundled PostgreSQL with PGVector:

pgvector:
  enabled: true
  auth:
    username: postgres
    password: "secure-password"
    database: postgres
    # Optional: Use existing secret
    # existingSecret: "pgvector-auth-secret"
    # usernameKey: "username"      # defaults to "username"
    # passwordKey: "password"      # defaults to "password"
    # databaseKey: "database"      # defaults to "database"

External PostgreSQL with PGVector:

pgvector:
  enabled: false
  external:
    host: "my-pgvector.example.com"
    port: 5432
    user: "postgres"
    password: "secure-password"
    database: "postgres"
    # Optional: Use existing secret
    # existingSecret: "pgvector-external-secret"
    # existingSecretHostKey: "host"
    # existingSecretUserKey: "user"
    # existingSecretPasswordKey: "password"
    # existingSecretDatabaseKey: "database"

Important: External PostgreSQL with PGVector must have the vector, vectorchord, and vectorchord-bm25 extensions installed. The bundled PostgreSQL with PGVector uses an image which includes all required extensions.

Database Secrets Management

For production deployments, use Kubernetes secrets instead of plain text passwords:

# Create PostgreSQL secret
kubectl create secret generic postgresql-auth-secret \
  --from-literal=username=helix \
  --from-literal=password=secure-password \
  --from-literal=database=helix

# Create PostgreSQL with PGVector secret  
kubectl create secret generic pgvector-auth-secret \
  --from-literal=username=postgres \
  --from-literal=password=secure-password \
  --from-literal=database=postgres

# Create controlplane secrets
kubectl create secret generic runner-token-secret \
  --from-literal=token=your-secure-runner-token-here

kubectl create secret generic keycloak-auth-secret \
  --from-literal=user=admin \
  --from-literal=password=your-secure-keycloak-admin-password

# Create provider API key secrets
kubectl create secret generic openai-credentials \
  --from-literal=api-key=sk-your-openai-api-key

kubectl create secret generic anthropic-credentials \
  --from-literal=api-key=sk-ant-your-anthropic-api-key

kubectl create secret generic together-credentials \
  --from-literal=api-key=your-together-api-key

kubectl create secret generic vllm-credentials \
  --from-literal=api-key=your-vllm-api-key

Deploying a Runner

This section describes how to install a Helix runner on Kubernetes.

1. Install the Helm Repository

helm repo add helix https://charts.helixml.tech 
helm repo update

2. Apply the Chart

Then, install the runner:

export LATEST_RELEASE=$(curl -s https://get.helixml.tech/latest.txt)
helm upgrade --install my-helix-runner helix/helix-runner \
  --set runner.host="my-helix-controlplane" \
  --set runner.token="oh-hallo-insecure-token" \
  --set runner.memory=24GB \
  --set replicaCount=1 \
  --set image.tag="${LATEST_RELEASE}-small"

More Help

If you get stuck, please get in touch. But here’s some extra links to help you get deployed:

Last updated on