The chart's own helm/sim/README.md is the reference for every value, and goes deeper than this page on secret strategies, network policy, PII redaction, and per-error troubleshooting. This page covers the deployment path; read that alongside it.
Prerequisites
- Kubernetes 1.25+
- Helm 3.8+
- PV provisioner support (a default StorageClass supporting
ReadWriteOnce) - An ingress controller, if
ingress.enabled=true metrics-server, if you enable autoscaling- Redis — bundled by the chart (
redis.enabled: true). To use your own, setapp.env.REDIS_URL: a non-empty value overrides the bundled URL and suppresses its Deployment on its own.redis.enabled: falseis the explicit opt-out. See Redis
Installation
The chart is published to GitHub Container Registry as an OCI artifact at
oci://ghcr.io/simstudioai/charts/sim. Install it directly — no clone required.
It is also available from a classic Helm repository at https://charts.sim.ai
for tooling that expects one; see Helm repository below.
Prefer OCI where you can, since the signature and provenance are attached to the
OCI artifact.
# Generate secrets
BETTER_AUTH_SECRET=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
INTERNAL_API_SECRET=$(openssl rand -hex 32)
API_ENCRYPTION_KEY=$(openssl rand -hex 32)
CRON_SECRET=$(openssl rand -hex 32)
POSTGRES_PASSWORD=$(openssl rand -hex 24)
# Install
helm install sim oci://ghcr.io/simstudioai/charts/sim \
--version 1.9.5 \
--set app.env.BETTER_AUTH_SECRET="$BETTER_AUTH_SECRET" \
--set app.env.ENCRYPTION_KEY="$ENCRYPTION_KEY" \
--set app.env.INTERNAL_API_SECRET="$INTERNAL_API_SECRET" \
--set app.env.API_ENCRYPTION_KEY="$API_ENCRYPTION_KEY" \
--set app.env.CRON_SECRET="$CRON_SECRET" \
--set postgresql.auth.password="$POSTGRES_PASSWORD" \
--namespace simstudio --create-namespaceSave all six values somewhere durable before moving on. ENCRYPTION_KEY in particular cannot be regenerated — losing it makes workspace environment variables and stored provider keys permanently unreadable.
API_ENCRYPTION_KEY is optional, and the failure mode is silent: leave it unset and Sim stores user-generated API keys in plain text, logging one warning and nothing else. Set it at install time — it must be a 64-character hex string, which is exactly what openssl rand -hex 32 produces — and back it up like ENCRYPTION_KEY.
CRON_SECRET is required whenever background jobs are enabled, which is the chart's default: the chart will not render without it, unless it comes from app.secrets.existingSecret or External Secrets — in which case the key must be present there or every cron pod fails to start. Set cronjobs.enabled=false instead if you deliberately want no scheduled jobs.
This installs the chart's default image tag. For production, pin app, realtime, and migrations to the same explicit release tag — see Upgrades.
Helm repository
For clusters or GitOps configs that consume helm repo add rather than OCI:
helm repo add sim https://charts.sim.ai
helm repo update
helm install sim sim/sim --version 1.9.5 --namespace simstudio --create-namespace \
--set app.env.BETTER_AUTH_SECRET="$BETTER_AUTH_SECRET" \
--set app.env.ENCRYPTION_KEY="$ENCRYPTION_KEY" \
--set app.env.INTERNAL_API_SECRET="$INTERNAL_API_SECRET" \
--set app.env.API_ENCRYPTION_KEY="$API_ENCRYPTION_KEY" \
--set app.env.CRON_SECRET="$CRON_SECRET" \
--set postgresql.auth.password="$POSTGRES_PASSWORD"It serves the same chart as the OCI registry. The signature and provenance below apply to the OCI artifact only.
Verifying the chart
Every published version is signed with Sigstore keyless signing and carries a SLSA build-provenance attestation. Both live in the registry alongside the chart, so they survive a mirror into an internal registry.
cosign verify oci://ghcr.io/simstudioai/charts/sim:1.9.5 \
--certificate-identity-regexp '^https://github.com/simstudioai/sim/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify oci://ghcr.io/simstudioai/charts/sim:1.9.5 --repo simstudioai/simSigning is Sigstore-only — there is no GPG .prov file, so helm install --verify does not apply.
Verification requires cosign v3.0 or newer. Signatures use the Sigstore protobuf bundle format, which cosign v3 writes by default and cosign v2 cannot read. cosign v3.1+ auto-detects both formats.
Cloud-Specific Values
These are cloud-tuned alternatives to the generic install above — pick one path, don't run both. The commands reuse the $BETTER_AUTH_SECRET, $ENCRYPTION_KEY, $INTERNAL_API_SECRET, $API_ENCRYPTION_KEY, $CRON_SECRET, and $POSTGRES_PASSWORD variables generated in Installation above, so run that block's openssl lines first in the same shell. They use helm upgrade --install, so they work whether or not a release exists yet. Two caveats when converting an existing generic install rather than starting fresh: (1) reuse the original secret values — recover them with helm get values sim -n simstudio if your shell no longer has them; supplying a newly generated ENCRYPTION_KEY makes every previously encrypted value (workspace environment variables, stored provider keys, MCP OAuth credentials) undecryptable. (2) The cloud values rename the bundled PostgreSQL database to simstudio, but Postgres only applies that setting on first initialization — add --set postgresql.auth.database=sim to keep your existing database. If you'd rather start clean, helm uninstall sim -n simstudio, delete its PVCs, and run the cloud command fresh.
# The example values files are not part of the packaged chart, so fetch the one
# you want at a release tag — pinning the chart but reading values off a moving
# branch would still make this command produce different deployments over time.
SIM_RELEASE=v0.8.24
curl -fsSLO "https://raw.githubusercontent.com/simstudioai/sim/$SIM_RELEASE/helm/sim/examples/values-aws.yaml"
helm upgrade --install sim oci://ghcr.io/simstudioai/charts/sim \
--version 1.9.5 \
--values values-aws.yaml \
--set app.env.BETTER_AUTH_SECRET="$BETTER_AUTH_SECRET" \
--set app.env.ENCRYPTION_KEY="$ENCRYPTION_KEY" \
--set app.env.INTERNAL_API_SECRET="$INTERNAL_API_SECRET" \
--set app.env.API_ENCRYPTION_KEY="$API_ENCRYPTION_KEY" \
--set app.env.CRON_SECRET="$CRON_SECRET" \
--set postgresql.auth.password="$POSTGRES_PASSWORD" \
--set app.env.NEXT_PUBLIC_APP_URL="https://sim.yourdomain.com" \
--set app.env.BETTER_AUTH_URL="https://sim.yourdomain.com" \
--set app.env.NEXT_PUBLIC_SOCKET_URL="https://sim-ws.yourdomain.com" \
--set realtime.env.ALLOWED_ORIGINS="https://sim.yourdomain.com" \
--set ingress.app.host="sim.yourdomain.com" \
--set ingress.realtime.host="sim-ws.yourdomain.com" \
--namespace simstudio --create-namespaceEvery one of those overrides is required. The cloud values files hardcode a placeholder domain in all six places, and overriding only NEXT_PUBLIC_APP_URL leaves sign-in pointed at the placeholder, realtime rejecting every socket upgrade, and the Ingress serving the wrong host.
Swap the --values file for your cloud: values-aws.yaml (EKS), values-azure.yaml (AKS), or values-gcp.yaml (GKE). Everything else is identical. Keep the downloaded file in your own config repo — the --set overrides above cover the six placeholder domains, but anything else you tune belongs in the file.
Key Configuration
# Custom values.yaml
app:
replicaCount: 2
image:
tag: "v1.2.3" # a tag from the releases page
env:
NEXT_PUBLIC_APP_URL: "https://sim.yourdomain.com"
BETTER_AUTH_URL: "https://sim.yourdomain.com"
OPENAI_API_KEY: "sk-..."
# Only needed when redis.enabled is false — the bundled Redis is injected otherwise
REDIS_URL: "redis://:<password>@redis.internal:6379"
realtime:
image:
tag: "v1.2.3" # a tag from the releases page
migrations:
image:
tag: "v1.2.3" # a tag from the releases page
postgresql:
persistence:
size: 50Gi
ingress:
enabled: true
className: nginx
tls:
enabled: true
app:
host: sim.yourdomain.comNEXT_PUBLIC_APP_URL and BETTER_AUTH_URL must both be your real public origin. Leaving either at localhost breaks sign-in.
Keys set under app.env land on the realtime pod too — the chart writes them into one Secret that both Deployments consume via envFrom. Use realtime.env only for keys that must differ between the two, such as ALLOWED_ORIGINS.
The chart ships Redis (redis.enabled: true) and injects its REDIS_URL into both the app and realtime Deployments, so raising replicaCount works out of the box. The hazard is setting redis.enabled: false without supplying app.env.REDIS_URL: cross-pod events are then dropped with no error anywhere, silently breaking live collaboration and status updates. See Redis and Scaling & HA.
See helm/sim/values.yaml for all options, and the chart's README for the production checklist.
Background jobs
The chart deploys CronJobs by default, driving scheduled workflows, polling triggers, connector syncs, OAuth token cleanup, data drains, and outbox processing. They require CRON_SECRET; set cronjobs.enabled=false to deploy none.
kubectl get cronjobs -n simstudioA CronJob with a stale LAST SCHEDULE means the corresponding feature has stopped working. See Background Jobs.
Ingress and TLS
For nginx-style ingress controllers, raise the body-size and timeout limits — Sim's defaults allow large chat attachments and long-running executions:
ingress:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "250m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-buffering: "off"On GKE, the load balancer's 30-second default backend timeout closes websockets and needs a BackendConfig, and the ManagedCertificate the chart references must be created by you. Both are covered in Networking.
External Database
postgresql:
enabled: false
externalDatabase:
enabled: true
host: "your-db-host"
port: 5432
username: "postgres"
password: "your-password"
database: "simstudio"
sslMode: "require"Commands
# Port forward for local access
kubectl port-forward deployment/sim-app 3000:3000 -n simstudio
# View logs
kubectl logs -l app.kubernetes.io/component=app -n simstudio --tail=100
# Upgrade (always pin the target chart version)
helm upgrade sim oci://ghcr.io/simstudioai/charts/sim --version 1.9.5 --namespace simstudio
# Uninstall
helm uninstall sim --namespace simstudio