Skip to main content
Complete every item on this checklist before running helm install. Most installation failures trace back to a missed prerequisite or a known chart quirk listed here.

Cluster

  • Kubernetes 1.27+ (1.32+ recommended)
  • Worker nodes are AMD64 (x86_64) — ARM64 is not supported
  • AWS: AWS Load Balancer Controller installed
  • GCP: Workload Identity enabled on cluster and node pools; Gateway API enabled if using GKE Gateway
  • Azure: NGINX Ingress Controller or Azure Application Gateway installed
  • Helm 3.10+ installed locally
  • kubectl configured and pointing at the correct cluster and namespace

Databases

All four databases must exist before helm install. The Helm pre-install hook runs migrations immediately — if any database is missing, the hook fails and the release is left in a broken state.
Create these databases on your managed PostgreSQL instance before installing:
envVars keyDatabase name to create
POSTGRES_DBcrewai_plus_production
POSTGRES_CABLE_DBcrewai_plus_cable_production
POSTGRES_OAUTH_DBcrewai_plus_oauth_production
wharf (Wharf service)wharf
CREATE DATABASE crewai_plus_production;
CREATE DATABASE crewai_plus_cable_production;
CREATE DATABASE crewai_plus_oauth_production;
CREATE DATABASE wharf;

GRANT ALL PRIVILEGES ON DATABASE crewai_plus_production TO <db_user>;
GRANT ALL PRIVILEGES ON DATABASE crewai_plus_cable_production TO <db_user>;
GRANT ALL PRIVILEGES ON DATABASE crewai_plus_oauth_production TO <db_user>;
GRANT ALL PRIVILEGES ON DATABASE wharf TO <db_user>;
GCP Cloud SQL IAM auth: GRANT ALL PRIVILEGES ON DATABASE is not sufficient for Cloud SQL IAM-authenticated users. Schema-level grants are also required. See the GCP Integration Guide for the complete SQL.
POSTGRES_OAUTH_DB default mismatch: The chart default for POSTGRES_OAUTH_DB is oauth_db. If you create the database as crewai_plus_oauth_production (recommended) but do not override POSTGRES_OAUTH_DB in envVars:, the app connects to a non-existent database and authentication fails silently. Always set POSTGRES_OAUTH_DB explicitly:
envVars:
  POSTGRES_OAUTH_DB: "crewai_plus_oauth_production"

Auth Provider

  • WorkOS: Redirect URI https://<your-domain>/auth/workos/callback added in WorkOS Dashboard → Applications → your app
  • Entra ID: Redirect URI https://<your-domain>/auth/entra_id/callback registered in Azure App Registration (Web platform). Must be done before helm install — auth fails at login if missing.
  • Okta: Sign-in redirect URI https://<your-domain>/auth/okta/callback configured in Okta app
  • Keycloak: Valid redirect URI https://<your-domain>/auth/keycloak/callback added to the Keycloak client

Cloud IAM / Credentials

  • AWS (Pod Identity): Pod Identity association created for crewai-sa ServiceAccount with S3 + ECR permissions
  • AWS (IRSA): IRSA trust policy references correct namespace and ServiceAccount name (crewai-sa)
  • GCP: GSA created with required IAM roles; Workload Identity binding created for crewai-sa
  • Azure: Managed Identity created; federated credential configured for crewai-sa ServiceAccount

Container Registry

  • ECR / ACR / GAR repository created with path ending in /crewai-enterprise
  • ECR: Image tag mutability set to MUTABLE (CrewAI overwrites image tags)
  • CREW_IMAGE_REGISTRY_OVERRIDE set to the registry prefix only — do not include /crewai-enterprise (the platform appends it automatically)

Known Chart Gotchas

These are silent failures — the chart installs without errors but the platform behaves incorrectly at runtime.
WORKOS_API_KEY and WORKOS_COOKIE_PASSWORD must be under envVars:, not secrets:. This is a known chart limitation: the secrets template does not render these values into pod environments. Placing them under secrets: causes WorkOS authentication to fail with no error message in application logs.
# ✅ Correct
envVars:
  WORKOS_API_KEY: "sk_live_..."
  WORKOS_COOKIE_PASSWORD: "your-32-char-string"

# ❌ Wrong — silently ignored
secrets:
  WORKOS_API_KEY: "sk_live_..."
WORKOS_COOKIE_PASSWORD must also be 32 characters or fewer. Generate with:
openssl rand -base64 32 | cut -c -32

Entra ID: client ID and tenant ID placement

ENTRA_ID_CLIENT_ID and ENTRA_ID_TENANT_ID are non-sensitive identifiers and must be under envVars:. Only ENTRA_ID_CLIENT_SECRET belongs under secrets:. The chart does not inject Entra ID identity values from the secrets section into pod environments — placing them there causes silent authentication failures.
# ✅ Correct
envVars:
  ENTRA_ID_CLIENT_ID: "<Application client ID>"
  ENTRA_ID_TENANT_ID: "<Directory tenant ID>"
secrets:
  ENTRA_ID_CLIENT_SECRET: "<client secret value>"

# ❌ Wrong
secrets:
  ENTRA_ID_CLIENT_ID: "..."   # silently absent from pods
  ENTRA_ID_TENANT_ID: "..."   # silently absent from pods

AWS ALB: SSL termination

web.enableSslFromPuma must be set to false when using an AWS ALB. The chart default is true. ALB terminates TLS and forwards plain HTTP to backend pods; with the default true, Puma expects HTTPS and returns 502 Bad Gateway on every request.
web:
  enableSslFromPuma: false  # required for ALB

AWS ALB: scheme casing

The alb.scheme value is case-sensitive. The AWS Load Balancer Controller accepts only lowercase:
  • "internet-facing" / "internal"
  • "Internet-Facing" / "Internal" — silently fails to provision the ALB

GCP: signed URL generation

Set GCS_IAM_SIGNING: "true" in envVars: whenever using GCP Workload Identity for GCS. Without it, the platform attempts to sign GCS URLs using a service account key file that does not exist in Workload Identity environments. The error (Google::Cloud::Storage::SignedUrlUnavailable) only appears when users access uploaded files — the install and health checks succeed, making this easy to miss.
envVars:
  GCS_IAM_SIGNING: "true"

ECR: do not set global.imageRegistry for crew builds only

global.imageRegistry redirects all platform image pulls — Redis, BuildKit, Wharf, busybox, the main application — away from images.crewai.com. Setting it without a complete image mirror causes ImagePullBackOff on every pod.For crew image builds only, use CREW_IMAGE_REGISTRY_OVERRIDE instead and leave global.imageRegistry unset:
# ✅ Correct — for crew builds only
envVars:
  CREW_IMAGE_REGISTRY_OVERRIDE: "123456789012.dkr.ecr.us-east-1.amazonaws.com/my-org"

# ❌ Wrong — unless you have a full platform image mirror
global:
  imageRegistry: "123456789012.dkr.ecr.us-east-1.amazonaws.com"
See the Private Registry guide if you need a full image mirror.

Studio V2 has no Helm values

Studio V2 cannot be configured in values.yaml. Setting studioV2.enabled, STUDIO_V2_ENABLED, or similar keys has no effect — Helm silently ignores unrecognized keys. Studio V2 requires post-install setup via the web UI and kubectl exec commands. See Enable Studio V2 for the complete setup sequence.

Admin users have no Helm key

There is no adminUsers key in the chart. Admin roles are granted after install via:
kubectl exec -it deploy/crewai-web -- bin/rails 'factory:grant_admin[admin@company.com]'
Exception: Entra ID users receive admin access by assigning the factory-admin App Role in the Azure portal. factory:grant_admin has no effect for Entra ID users.

ArgoCD / GitOps: auto-generated secrets

The chart auto-generates several secrets (SECRET_KEY_BASE, ENCRYPTION_KEY, OAUTH_DB_ENCRYPTION_KEY, FACTORY_DEBUG_TOKEN, WHARF_JWT_SECRET, CUBE_JWT_SECRET, DEPLOYMENT_INSTANCE_JWT_SECRET) using the Helm lookup function, which does not work in GitOps pipelines. If deploying via ArgoCD or Flux, set these explicitly in your values. Generate with:
openssl rand -hex 32
See the ArgoCD Deployment Guide for the complete list and configuration.