Deploy Sim on a Kubernetes cluster you operate. The chart bundles PostgreSQL with pgvector and Redis, runs migrations before the app starts, and enables scheduled jobs by default.
The examples pin published chart 1.11.8, whose published app version is v0.9.17. This is a pinned example, not a claim about the newest release. Inspect the chart values or run helm show values oci://ghcr.io/simstudioai/charts/sim --version 1.11.8 for its configuration.
Prerequisites
- A maintained Kubernetes cluster. The chart's declared compatibility minimum is 1.25.
- Helm 3.8 or later for OCI installation.
- A default StorageClass supporting
ReadWriteOncefor bundled PostgreSQL. - An installed ingress controller if you enable ingress, plus a certificate for public TLS.
metrics-serverif you enable autoscaling.- External Secrets Operator and a configured SecretStore/ClusterSecretStore if you choose that secret strategy.
Redis is bundled by default. A non-empty app.env.REDIS_URL overrides its URL and suppresses the bundled Redis Deployment. redis.enabled=false is the explicit opt-out; supply an external URL if you need cross-replica events. See Redis.
Installation
1. Choose the secret strategy
In existing-Secret mode, non-empty app.env and realtime.env values are inlined into pod specs. Keep secret material in the pre-created Secret. In ESO mode, every non-empty key under those env maps must also have a remote reference; the chart rejects missing mappings. Put non-secret URL/configuration values in envDefaults instead.
2. Prepare new-install secrets
The following installation uses inline values to demonstrate a local release. For an existing release, recover and retain its current values rather than generating replacements. For a secret-store installation, store the same required values there and use the secret-store examples.
CRON_SECRET is required with the default cronjobs.enabled=true. The chart rejects an absent inline value. With an existing Secret, the key must be present there; with ESO, it must be mapped. Set cronjobs.enabled=false only if you intend to run no chart-scheduled jobs.
3. Install the pinned chart
Ingress is disabled by default. For local access, forward the app and realtime ports in separate terminals:
Open http://localhost:3000. For public access, complete the topology below and apply it with the same secrets or secret-store configuration.
Public access
Configure a public app origin, realtime routing, allowed origins, and TLS together. This same-host example belongs in public-values.yaml; replace the ingress class with your installed controller's class:
The app and realtime consume shared app env values; ALLOWED_ORIGINS explicitly admits the public app origin. Matching ingress hosts lets the chart route /socket.io before the app's / path. Keep app, realtime, and migrations on the same image release.
Create sim-tls in simstudio from your certificate and private key, or configure your certificate manager to populate that Secret:
For a fresh public installation, create the namespace before creating the Secret. Configure DNS and the controller's own HTTPS redirect, upload-size, WebSocket, timeout, and streaming settings. The null above removes the chart's legacy nginx redirect annotation; it does not configure another controller.
For a separate realtime hostname, change all three fields together:
Keep ALLOWED_ORIGINS set to the app origin, and use a TLS certificate covering both hosts. App/auth URLs remain on sim.yourdomain.com.
Apply your complete values with helm upgrade --install, retaining the same secrets as installation. For inline mode, repeat the secret --set arguments from the install command and add -f public-values.yaml. For secret-store mode, use a complete values file defining that strategy.
Ingress and TLS
The chart defaults still name nginx and its annotations. Kubernetes ingress-nginx retired in March 2026 and no longer receives security fixes. Use a maintained controller supported by your cluster; the chart renders Ingress objects and does not provision a controller or Gateway API resources. See the Kubernetes retirement announcement.
For an existing legacy ingress-nginx deployment, these settings describe the required body-size and streaming behavior:
These annotations do not apply to other controllers. On GKE, configure a BackendConfig timeout for long-lived WebSockets and create the ManagedCertificate referenced by the values. See Networking.
Secret stores
Existing Secret
Prepare an app Secret containing at least BETTER_AUTH_SECRET, ENCRYPTION_KEY, INTERNAL_API_SECRET, API_ENCRYPTION_KEY, and CRON_SECRET, plus any provider credentials you use. For bundled PostgreSQL, prepare its password Secret too:
Use the public URL configuration above without putting credentials under app.env. Both Deployments consume the app Secret. See the complete existing-Secret example.
External Secrets Operator
Populate the remote keys and create the referenced store before installing. For a same-host public installation, move URL values from app.env and realtime.env into these envDefaults maps, then add the ingress/TLS configuration above:
Map additional credentials, such as RESEND_API_KEY, under remoteRefs.app. Remote value changes do not themselves restart processes; recreate the affected pods after credentials change. See the complete ESO example.
Configure model provider keys, such as OPENAI_API_KEY, through the same selected secret strategy. A healthy release does not establish that a model provider is configured.
Cloud-specific values
Use a cloud example as a starting file, not a complete install configuration. Fetch it from the release corresponding to the pinned chart example:
Choose values-aws.yaml for EKS, values-azure.yaml for AKS, or values-gcp.yaml for GKE. Review and replace provider-specific fields before installation:
Each file also has six placeholder public-address values. In inline mode, reuse your saved secrets and override those addresses together:
Replace the file name for another cloud and keep your reviewed file in your configuration repository. With ESO, use its env/default and remote-reference rules rather than the inline-secret arguments.
For an inline installation, helm get values sim -n simstudio can recover saved values. For external secret modes, use the existing secret store. Do not generate new encryption keys during conversion.
Verify the release
Scheduled jobs cover workflows, polling triggers, connector syncs, token cleanup, data drains, and outbox processing. Inspect failed job pods and endpoint responses, then run Verify your install.
Verify the chart
Published charts have Sigstore keyless signatures and build-provenance attestations in the source registry. Use cosign 3.0 or later for the bundle format; 3.1+ auto-detects old and new formats:
There is no GPG .prov file; helm install --verify does not verify these signatures. When mirroring charts, copy the associated signature and attestation artifacts as well as the chart. A chart-only copy does not preserve verification material.
External database
Configure a database with pgvector and the required migration permissions. The chart constructs the shared app/realtime/migration DSN from:
Replace the credentials or supply the chart's external-database Secret strategy. Inline passwords must use letters, digits, ., _, or - to pass chart DSN validation. See Cloud platforms and Upgrades for extensions and direct migration connections.
Helm repository
For tooling that requires a classic repository:
Use sim/sim in place of the OCI URL in the install/upgrade command, preserving the version, complete values, namespace, and secret configuration. Signature/provenance verification above applies to the OCI artifact.
Operator commands
Upgrade with the full configuration and an explicitly chosen chart version:
Retain the original secrets. See Upgrades before changing the target version.
Uninstall removes the release but leaves PostgreSQL StatefulSet PVCs: