Skip to main content

Upgrade your Helm deployment

This guide covers upgrading an existing self-hosted Retool Helm + Kubernetes deployment to Retool 4.0 and enabling features associated with the new app builder. These features are disabled by default in chart version 6.11.5 and must be explicitly enabled via the rr.* namespace in your Helm values. Upgrading the chart without enabling them is safe and fully backward compatible.

Retool's officially supported deployment configuration for Kubernetes is the Terraform blueprints. This guide is provided for customers upgrading existing Helm deployments and is offered for convenience, but Retool recommends migrating to the Terraform blueprints deployment for full support going forward.

Reference configuration for all steps is available in the retool-helm repository and Terraform blueprints.

What changed from Retool 3.x

Retool 4.0 introduces breaking changes to the Helm chart that affect existing values files:

ChangeDetails
Helm values restructured under rr.*All components required for the new app builder (jsExecutor, agentSandbox, rrGitServer) move under a single rr: key with rr.enabled: true as the master switch. The old top-level keys cause the chart to fail loudly — this is intentionally not backwards compatible.
Blob storage is now requiredObject storage (S3, Azure Blob, or GCS) is a platform requirement for app storage, Git repository storage, and sandbox snapshots. It was optional in Retool 3.x.
SecretsThe agent sandbox requires a new, unique JWT keypair and an encryption key, and you cannot reuse any existing JWT signing credentials or encryption keys. Postgres is inherited from the backend automatically (including SSL) — no separate schema config needed.
mcp stays top-levelThe MCP service uses mcp.enabled: true, not rr.mcp. It requires separate OAuth configuration and is not part of the rr.enabled master switch.

Before you upgrade

Use this checklist as you prepare the upgrade to ensure you have everything ready.

After upgrading, a database migration runs automatically in the background. Monitor your instance for a banner in Settings pages — if it appears, an admin can trigger the migration again from there. See Permissions database migration for details.

Update the Helm chart repository

Update your local chart cache to make chart version 6.11.5 available:

helm repo add retool https://charts.retool.com
helm repo update

Verify the chart is available:

helm search repo retool/retool --versions | grep 6.11.5

Terraform

Set the repository and version in your helm_release resource:

resource "helm_release" "retool" {
repository = "https://charts.retool.com"
chart = "retool"
version = "6.11.5"
# ...
}

Add core values

Add the following to your values.yaml. Use image tag 4.0.3-stable. Replace yourdomain.com with your existing Retool base domain (the current value of BASE_DOMAIN):

Enabling app builder services requires a custom Linux seccomp profile on each cluster node. The agent sandbox uses gVisor for sandboxing and will fail to start without it. The js-executor uses NsJail and has the same seccomp requirement. Both profiles are published in the Helm chart. Amazon EKS supports custom seccomp profiles by default. If your cluster has a restrictive security policy, verify this before enabling.

image:
tag: X.Y.Z-stable # use the tag shown above

rr:
enabled: true # master switch: enables agent, js-executor, agent-sandbox, and git-server

agentSandbox:
externalSecret:
name: 'agent-sandbox-env'
proxy:
backendDomainSuffixes: "yourdomain.com" # replace with your Retool base domain

mcp:
enabled: true # optional; requires separate OAuth config; NOT included in rr.enabled

Replace X.Y.Z-stable with the current stable version from the release notes. The minimum supported version for Retool 4.0 is 4.0.0-stable.

To disable a single component while keeping the master switch on, override it explicitly:

rr:
enabled: true
jsExecutor:
enabled: false # overrides master switch for this component only

The agent sandbox inherits the backend Postgres connection automatically on a separate internal schema. No postgres: config is needed unless your backend database password is injected via envFrom or an external secret. When the backend uses SSL (config.postgresql.ssl_enabled), the inherited connection automatically uses sslmode=no-verify.

Create agent sandbox secrets

The JWT keypair and the encryption key are required. Without them, the agent sandbox proxy fails to serve a sandbox. The API secret is optional.

Do not reuse the backend config.jwtSecret or any existing JWT signing credentials. Likewise, generate a unique agent sandbox encryption key rather than reusing the backend encryption key.

Generate the new secrets with the following commands:

# Generate a new private key
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out private_key.pem

# Derive the public key
openssl pkey -in private_key.pem -pubout -out public_key.pem

# Generate the encryption key — exactly 64 hex characters (base64 is rejected at runtime).
# tr -d '\n' drops openssl's trailing newline; without it the Secret holds 65 bytes and fails.
openssl rand -hex 32 | tr -d '\n' > encryption_key.txt

Create a Kubernetes Secret with the keypair:

cat > agent-sandbox-env.yaml << EOF
apiVersion: v1
kind: Secret
metadata:
name: agent-sandbox-env
namespace: default # use the namespace where Retool is deployed
type: Opaque
data:
jwt-public-key: $(cat public_key.pem | base64 -w0)
jwt-private-key: $(cat private_key.pem | base64 -w0)
encryption-key: $(cat encryption_key.txt | base64 -w0)
# Optional additional keys:
# api-secret: ...
# postgres-url: ... (only if your backend DB password is injected via envFrom)
EOF

kubectl apply -f agent-sandbox-env.yaml

The externalSecret.name reference in your values.yaml (already included in the core values block above) tells the agent sandbox where to find this secret.

For Terraform users, refer to secrets.tf for creating these secrets within Terraform and mapping them into Kubernetes via External Secrets Operator.

Configure blob storage

Each deployment requires an object storage bucket with read/write credentials. Use the rr.blobStorage: block in values.yaml. The chart renders the required environment variables automatically.

All subsystems share this one bucket and credential set, separated by internal path prefixes. The blobStorage: block can't point individual subsystems at different buckets. Instead, set the per-subsystem env vars (RR_GIT_S3_* and RR_SNAPSHOTS_S3_*, including their own credentials) directly. Note that accessKeyId is plaintext only; to source it from a secret, set RR_DEFAULT_S3_ACCESS_KEY_ID via environmentSecrets.

rr:
blobStorage:
s3:
bucket: <your-bucket>
region: <your-region>
accessKeyId: <key-id>
secretAccessKey: <secret> # or use secretAccessKeySecretName / secretAccessKeySecretKey
endpoint: "" # optional; for S3-compatible stores

IAM roles are supported as an alternative to access keys. For Terraform users, refer to the S3 and IAM reference configuration.

When the git server is enabled, the chart validates that exactly one blob storage provider is configured in the rr.blobStorage: block and fails the render if not. If you configure storage any other way — credentials injected via envFrom (e.g., a ConfigMap or Secret splat), or the per-subsystem env vars above (RR_GIT_S3_* / RR_SNAPSHOTS_S3_*) instead of the rr.blobStorage: block — set rr.gitServer.skipBlobStorageValidation: true to downgrade that hard error to a non-fatal warning.

Configure networking

The agent sandbox uses same-origin networking by default — it routes through your existing Retool ingress with no additional configuration. Your existing ingress block is unchanged:

ingress:
enabled: true
ingressClassName: '' # your existing value
hosts:
- host: yourdomain.com
paths:
- path: '/'
pathType: Prefix

No wildcard TLS certificate, wildcard DNS, or separate ingress route is required. The MCP service (https://yourdomain.com/mcp/*) is also routed through the existing ingress automatically.

Cloud-specific details

Amazon EKS Karpenter

Karpenter is incompatible with the current agent sandbox architecture. The agent-sandbox-job pods use an extended resource (smarter-devices/net_tun) that Karpenter cannot schedule correctly.

To fix this: run a recent version of Karpenter with the nodeOverlay feature gate enabled, and create a NodeOverlay custom resource. Refer to this reference configuration.

Google GKE device plugin PriorityClass

On GKE, the default device plugin priority class (rr.agentSandbox.devicePlugin.priorityClassName, set to system-node-critical) prevents the agent-sandbox-device-plugin DaemonSet pods from scheduling, because GKE requires a custom ResourceQuota to use the system-node-critical PriorityClass in user namespaces. Without the device plugin, the agent sandbox can't run.

Set the priority class to null in your values.yaml to resolve this:

rr:
agentSandbox:
devicePlugin:
priorityClassName: null

Apply the changes

Run the Helm upgrade:

helm upgrade retool retool/retool \
--version 6.11.5 \
-f values.yaml

Complete setup in the Retool UI

Once the deployment is healthy, an admin user should complete the following:

  1. Enable Temporal: click the Workflows nav item and follow the in-product setup steps to enable Temporal Cloud. A valid license key is required.
  2. Configure your organization to use the new app builder.