Helm Install
Errand can be deployed to any Kubernetes cluster using its official Helm chart. This is the recommended approach for production environments, teams, and anywhere you need high availability or autoscaling.
Prerequisites
Section titled “Prerequisites”- A running Kubernetes cluster (any provider — cloud or local)
- Helm 3 installed on your machine
- kubectl configured to access your cluster
- An API key from at least one LLM provider (e.g. Anthropic, OpenAI)
- A PostgreSQL database (the chart does not bundle one)
Step 1: Create Kubernetes secrets
Section titled “Step 1: Create Kubernetes secrets”Before installing the chart, create the secrets that Errand needs. Run these commands, replacing the placeholder values with your own:
-
Database credentials — connection string for PostgreSQL:
Terminal window kubectl create secret generic errand-database \--from-literal=DATABASE_URL="postgresql://user:password@hostname:5432/errand" -
LLM provider credentials — your API key:
Terminal window kubectl create secret generic errand-openai \--from-literal=OPENAI_API_KEY="your-api-key-here" -
Credential encryption key — used to encrypt stored integration credentials:
Terminal window kubectl create secret generic errand-encryption \--from-literal=CREDENTIAL_ENCRYPTION_KEY="$(python3 -c 'from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())')" -
Hindsight bearer token (only if you enable Hindsight agent memory):
Terminal window kubectl create secret generic errand-hindsight \--from-literal=HINDSIGHT_TOKEN="$(openssl rand -hex 32)"
Step 2: Install the Helm chart
Section titled “Step 2: Install the Helm chart”Install the chart directly from the OCI registry:
helm install errand oci://ghcr.io/errand-ai/charts/errand \ --set database.existingSecret=errand-database \ --set llmProviders[0].name=openai \ --set llmProviders[0].existingSecret=errand-openai \ --set credentialEncryption.existingSecret=errand-encryptionStep 3: Configure values
Section titled “Step 3: Configure values”The Helm chart is configured through a values.yaml file. Here are the key settings:
Replicas and scaling
Section titled “Replicas and scaling”| Value | Description | Default |
|---|---|---|
server.replicaCount | Number of API server replicas (the task manager runs in-process in the server) | 1 |
server.maxTurns | Maximum LLM reasoning turns per task | 200 |
server.maxConcurrentTasks | Optional operator override for concurrent tasks per replica (leave unset to manage in the admin UI) | unset |
Multiple server replicas are safe — the in-process task manager uses Postgres advisory locks to elect a single leader per task, so only one replica runs each task runner.
Secrets
Section titled “Secrets”| Value | Description |
|---|---|
database.existingSecret | Kubernetes secret containing DATABASE_URL |
llmProviders[].existingSecret | Kubernetes secret containing the LLM provider’s API key (one per provider entry) |
credentialEncryption.existingSecret | Kubernetes secret containing CREDENTIAL_ENCRYPTION_KEY |
hindsight.apiKey.secret | Kubernetes secret containing HINDSIGHT_TOKEN (only when Hindsight is enabled) |
gdrive.existingSecret | Kubernetes secret containing GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET |
onedrive.existingSecret | Kubernetes secret containing MICROSOFT_CLIENT_ID, MICROSOFT_CLIENT_SECRET, and MICROSOFT_TENANT_ID |
Networking
Section titled “Networking”| Value | Description | Default |
|---|---|---|
ingress.host | Domain name for the Errand UI | — |
ingress.tls.enabled | Enable HTTPS using cert-manager | false |
Built-in services
Section titled “Built-in services”| Value | Description | Default |
|---|---|---|
valkey.enabled | Deploy a built-in Valkey cache (recommended for single-cluster deployments; disable and supply VALKEY_URL to use an external instance) | true |
onedrive.enabled | Enable OneDrive integration | true |
playwright.enabled | Deploy the Playwright browser-automation sidecar | true |
hindsight.url | URL of an external Hindsight service (empty = don’t connect to Hindsight) | "" |
workspaceGateway.enabled | Enable the shared cloud workspace gateway (rclone NFS at /shared) | false |
To use a custom values file:
helm install errand oci://ghcr.io/errand-ai/charts/errand \ -f values.yamlStep 4: Verify the installation
Section titled “Step 4: Verify the installation”-
Check that the pods are running:
Terminal window kubectl get pods -l app.kubernetes.io/name=errand -
If you configured an ingress, open
https://your-domainin your browser. Otherwise, use port forwarding:Terminal window kubectl port-forward svc/errand-server 8000:8000 -
Navigate to http://localhost:8000 and log in
How task execution works
Section titled “How task execution works”The server’s in-process task manager uses Kubernetes Jobs to execute each task in an isolated pod. This means:
- Each task runs in its own container with its own resources
- A failed task does not affect other running tasks
- The server’s ServiceAccount needs RBAC permissions to create and manage Jobs, ConfigMaps, and Pods
The Helm chart automatically creates the required ServiceAccount and RBAC roles. If you are using a custom ServiceAccount, make sure it has permissions for jobs, configmaps, and pods in the Errand namespace.
Database options
Section titled “Database options”The chart does not include a built-in PostgreSQL instance. You need to provide your own database. Two common options:
- Managed database — use a cloud-hosted PostgreSQL service (e.g. AWS RDS, Google Cloud SQL, Azure Database for PostgreSQL) and pass the connection string via the
database.existingSecret - CloudNativePG — deploy PostgreSQL on Kubernetes using the CloudNativePG operator, which handles backups, failover, and high availability
Troubleshooting
Section titled “Troubleshooting”| Issue | Solution |
|---|---|
Pods stuck in Pending state | Check for resource constraints with kubectl describe pod <pod-name>. The cluster may not have enough CPU or memory available |
| Server pod crashes on startup | Check logs with kubectl logs <pod-name>. The most common cause is a missing or incorrect DATABASE_URL in the database secret |
| Tasks not starting | Check the server logs. The most common cause is a missing LLM provider API key secret or a wrong OPENAI_API_KEY |
| Cannot reach the UI through ingress | Confirm that ingress.host is set correctly, DNS points to your cluster, and (if using TLS) cert-manager has issued a certificate |
| LLM errors during task execution | Verify the LLM provider’s API key secret is correct and your account has available credits |