Linux & Kubernetes
Install Helix on a Linux server or Kubernetes cluster.
Licensing
A license is required to run Helix on Linux or Kubernetes.
- Developer license: For individuals, testing, and businesses with less than $10M annual revenue or fewer than 250 employees. Buy a developer license →
- Enterprise license: For larger organizations with full RBAC, SSO, SOC 2 Type II, and dedicated onboarding. Enterprise licensing →
Helix runs on any Kubernetes cluster - whether that's on your own bare metal, a European cloud provider like Hetzner or OVH, or a major cloud platform like AWS (EKS), Google Cloud (GKE), or Azure (AKS). If you can run containers, you can run Helix.
For organisations focused on digital sovereignty, we also offer a turnkey Sovereign Server - a 4U rack server with Helix pre-installed, shipped to your data centre.
Local Setup
To install Helix on your own Linux server with Nvidia/AMD GPU support, run the following command:
curl -sL -O https://get.helixml.tech/install.sh && bash install.shKubernetes Setup
Helm charts
Helix ships as three separate Helm charts, all published to https://charts.helixml.tech:
| Chart | Purpose | Required? |
|---|---|---|
helix-controlplane | Main Helix API, UI, RAG, and orchestration. This is what users log in to. | Yes |
helix-runner | GPU (or CPU) worker that runs LLM inference and embeddings on your own hardware. | Optional. Only needed if you want to run inference locally. Otherwise configure the control plane to use an external provider (OpenAI, Anthropic, vLLM, Together, etc.). |
helix-sandbox | Docker-in-Docker host for desktop agents, Zed sessions, and spec tasks (cloud desktops with GPU video streaming). | Recommended. Required if you use desktop or agent features. |
Most deployments install helix-controlplane and helix-sandbox. Add helix-runner only if you want to run inference locally on your own GPUs - most deployments wire inference to an external provider instead.
The sections below cover the install for all three charts.
Prerequisites
- A Kubernetes cluster (1.28+). Managed control planes (AKS/EKS/GKE) are fine; the sandbox chart requires privileged pods, so AKS/EKS/GKE Autopilot is not supported.
kubectlandhelm3.x on your workstation.- A Helix license key from your account.
- A
StorageClassthat supportsReadWriteOncepersistent volumes. The control plane chart provisions several PVCs (main Postgres, pgvector, kodit-vectorchord, controlplane data). - For a minimal control-plane-only install, budget ~8 vCPU / 24 GiB RAM of worker capacity. The control plane pod ships with a Haystack sidecar that loads a ~4 GB embedding model on first start.
- An LLM provider (OpenAI, Anthropic, or a self-hosted
helix-runnerwith GPUs). Without one, there will be no models available after first login.
Cloud quotas
On a fresh Azure/AWS/GCP subscription, most GPU SKU families have quota 0 by default. Before starting:
- AWS:
g5/p4dEC2 quotas per region. - Azure:
NVadsV710v5(AMD V710) orNC*/ND*(NVIDIA) families, plus "Total Regional vCPUs". - GCP:
nvidia-*GPU quotas per region.
Create secrets
Replace <paste-your-license-key> with the key from your account. Generate real random values for the postgres password and runner token; the example values below are placeholders.
# Create namespace and secrets
kubectl create namespace helix
kubectl config set-context --current --namespace=helix
# Use a random value here. This is the Postgres admin password.
kubectl create secret generic postgresql-auth-secret \
--from-literal=postgres-password="$(openssl rand -hex 16)" \
--from-literal=username="helix" \
--from-literal=password="" \
--from-literal=database="helix"
kubectl create secret generic pgvector-auth-secret \
--from-literal=username="postgres" \
--from-literal=password="" \
--from-literal=database="postgres"
kubectl create secret generic helix-pgvector-creds \
--from-literal=dsn="postgresql://postgres:@my-helix-controlplane-pgvector:5432/postgres"
kubectl create secret generic helix-license \
--from-literal=license-key="<paste-your-license-key>"
# Random token, used by sandbox/runner charts to auth back to the control plane
kubectl create secret generic helix-runner-secrets \
--from-literal=api-token="$(openssl rand -hex 32)"Configure values.yaml
Save this as values.yaml for the chart:
# Production-ready configuration for helix-controlplane
# For more options: https://github.com/helixml/helix/blob/main/charts/helix-controlplane/values-example.yaml
global:
# Public URL of your Helix deployment. Used for OAuth redirects, email
# links, and agent callbacks. If you are behind an ingress + TLS, set
# this to your real hostname (e.g. https://helix.example.com).
# For kubectl port-forward, the default below is fine.
serverUrl: http://localhost:8080
# Leave image.tag unset so the chart uses its pinned appVersion.
# Do NOT set it to "latest" - no :latest tag is published to GHCR.
# To pin a specific release, use e.g. tag: "2.9.31".
searxng:
enabled: true
chrome:
enabled: true
pgvector:
enabled: true
auth:
existingSecret: "pgvector-auth-secret"
usernameKey: "username"
passwordKey: "password"
databaseKey: "database"
persistence:
enabled: true
size: 50Gi
storageClass: ""
annotations: {}
accessModes:
- ReadWriteOnce
controlplane:
licenseKeyExistingSecret: "helix-license"
licenseKeyExistingSecretKey: "license-key"
runnerTokenExistingSecret: "helix-runner-secrets"
runnerTokenExistingSecretKey: "api-token"
admin:
userSource: "env"
userIds: "all"
haystack:
enabled: true
existingSecret: "helix-pgvector-creds"
existingSecretDsnKey: "dsn"
embeddingsModel: "MrLight/dse-qwen2-2b-mrl-v1"
embeddingsDim: "1536"
chunkSize: "1000"
chunkOverlap: "50"
chunkUnit: "word"
rag:
defaultProvider: "haystack"
embeddingsProvider: "helix"
inference:
defaultProvider: "helix"
fineTuning:
defaultProvider: "helix"
# Configure at least one LLM provider. Without this, there will be
# no models available after first login. Provide an API key inline,
# or reference a Kubernetes secret via controlplane.providers.<name>.apiKeyExistingSecret.
# providers:
# anthropic:
# apiKey: "sk-ant-..."
# openai:
# apiKey: "sk-..."
# Extra environment variables injected into the control plane pod.
# The control plane process is where settings like HELIX_ENCODER
# are read and forwarded to inner desktop containers spawned for
# spec task / Zed agent sessions.
#
# Example: opt into hardware H.264 video encoding on AMD GPUs
# (requires Helix 2.10.0+; no-op on 2.9.x). Default auto-detect uses
# software OpenH264 on AMD because of a historical gst-va crash on
# older Mesa; this flag bypasses that skip.
# extraEnv:
# - name: HELIX_ENCODER
# value: "vaapi"
persistence:
enabled: true
size: 100Gi
storageClass: ""
accessModes:
- ReadWriteOnce
volumes:
- name: data
postgresql:
enabled: true
auth:
existingSecret: "postgresql-auth-secret"
postgresPasswordKey: "postgres-password"
usernameKey: "username"
passwordKey: "password"
databaseKey: "database"
architecture: standalone
tika:
enabled: false
typesense:
enabled: falseExternal Postgres
The chart can use an existing managed Postgres instead of the bundled one, but the bundled pgvector sidecar requires the vectorchord and vectorchord-bm25 extensions. Managed services that ship stock Postgres (Azure Flexible Server, AWS RDS, Cloud SQL) do not include these extensions out of the box, so keep pgvector.enabled: true. That pod will host the RAG vector index independently of wherever your main Postgres lives.
Install the control plane
# Add Helix Helm repository
helm repo add helix https://charts.helixml.tech
helm repo update
# Install the control plane with your generated values.yaml and secrets.
# By default the chart uses its pinned appVersion. Do NOT set image.tag
# to "latest" - no :latest tag is published. To pin a specific release,
# add --set image.tag="<version>" (e.g. "2.9.31") or --version "<chart-version>".
helm upgrade --install my-helix-controlplane helix/helix-controlplane \
-f values.yamlFirst boot pulls the embedding model (~4 GB) into the Haystack sidecar; budget 5 to 10 minutes before the main pod becomes Ready.
External inference providers
Helix can route inference to external providers (OpenAI, Anthropic, Together, or any self-hosted OpenAI-compatible endpoint like vLLM) instead of running a local runner. Each provider is configured under controlplane.providers.* in the control-plane values. Use existingSecret for API keys so they stay out of your values file and git history.
First, create a Kubernetes Secret for each provider you want to use:
kubectl create secret generic openai-api-key \
--from-literal=api-key="sk-..."
kubectl create secret generic anthropic-api-key \
--from-literal=api-key="sk-ant-..."
kubectl create secret generic togetherai-api-key \
--from-literal=api-key="..."Then add a providers: block inside the controlplane: section of your values.yaml. Only include the providers you actually use:
controlplane:
# ... your existing controlplane config ...
providers:
openai:
existingSecret: "openai-api-key"
existingSecretApiKeyKey: "api-key"
# baseUrl: "https://api.openai.com/v1" # override for Azure OpenAI or proxies
anthropic:
existingSecret: "anthropic-api-key"
existingSecretApiKeyKey: "api-key"
togetherai:
existingSecret: "togetherai-api-key"
existingSecretApiKeyKey: "api-key"
vllm:
# Self-hosted vLLM speaks the OpenAI API. Point at its cluster-internal service.
# Most vLLM deployments need no API key; pass one via existingSecret if yours does.
baseUrl: "http://my-vllm.vllm.svc.cluster.local:8000/v1"Anthropic can also be used via GCP Vertex AI - set vertexProjectID, vertexRegion, and either vertexCredentialsJSON or vertexCredentialsSecret under providers.anthropic. See values.yaml in the chart for the full shape.
Re-run helm upgrade on the control plane to apply the change. With at least one external provider configured, you can skip the runner install in the next section.
Install the runner (optional, GPU inference)
Skip this section if you're using OpenAI/Anthropic/another hosted LLM provider configured via controlplane.providers.
The runner image tag has a GPU-class suffix:
-small(single consumer GPU: T4, L4, A10, RTX 4090)-large(larger GPU: A100/H100)
helm upgrade --install my-helix-runner helix/helix-runner \
--set runner.host="http://my-helix-controlplane:8080" \
--set runner.tokenExistingSecret="helix-runner-secrets" \
--set runner.tokenExistingSecretKey="api-token" \
--set replicaCount=1Install the sandbox chart (cloud desktops / Zed agent)
The helix-sandbox chart powers Helix's cloud desktop and in-browser Zed IDE features. It is optional; install it only if you want to run spec tasks or open the IDE in the browser.
The sandbox runs a Docker-in-Docker daemon which needs privileged pods, a GPU node pool (for desktop rendering), and large persistent volumes.
helm upgrade --install my-helix-sandbox helix/helix-sandbox \
--namespace helix \
--set sandbox.apiUrl="http://my-helix-controlplane.helix.svc.cluster.local" \
--set sandbox.runnerTokenExistingSecret=helix-runner-secrets \
--set sandbox.runnerTokenExistingSecretKey=api-tokenPer-cloud override values are shipped with the chart: values-aks.yaml, values-eks.yaml, values-gke.yaml, values-bare-metal.yaml.
Access the control plane
kubectl port-forward -n helix svc/my-helix-controlplane 8080:80Then open http://localhost:8080. The first registered user becomes an admin (because of controlplane.admin.userIds: "all").
For a production deployment you should configure an ingress with TLS termination and set global.serverUrl to the public URL. See the values-example.yaml for nginx + cert-manager, GKE managed-certificate, and cert-manager + DNS-01 examples.