Skip to main content

Overview

The CrewAI Platform Helm chart provides a production-ready deployment with:
  • PostgreSQL database (internal StatefulSet or external)
  • MinIO object storage (optional S3-compatible storage)
  • Background workers (Rails ActiveJob for async processing)
  • Web application (Rails-based with flexible ingress support)
  • Intelligent secret management with auto-population from Replicated license fields
  • Multi-provider ingress support (AWS ALB, NGINX, Istio)
  • BuildKit service for container image building

Quick Start for Production

Minimum Required Configuration

For a production deployment with external database and object storage:
my-values.yaml
This is a generic template. For cloud-specific values and infrastructure setup, see the AWS Guide, GCP Guide, or Azure Guide.
Do not set envVars.K8S_NAMESPACE. The chart automatically derives this value from crewNamespace (default: crewai-crews) and injects it into every pod. Setting it manually overrides the chart value and can cause crew workloads to schedule into the wrong namespace.
Helm silently ignores unrecognized keys. If you add a top-level key that does not exist in values.yaml (for example, adminUsers or studioV2.enabled), helm install and helm lint will not report an error, but the value has no effect — adding these keys has no effect. Always verify configuration keys against the Chart Values Reference.Features that cannot be pre-configured in values.yaml and require post-installation steps:
  • Admin users and org ownership — configure via kubectl exec after install. See the Post-Installation Guide.
  • Studio V2 — requires interactive UI setup plus kubectl exec commands. See the Post-Installation Guide and Studio V2 Setup Guide.

Critical Production Configuration Areas

1. Database Configuration

For External PostgreSQL (Recommended):
Database Pre-creation Required: When using an external PostgreSQL instance, you must manually create all required databases before deploying: primary, cable, OAuth, and Wharf (wharf by default, enabled by default). See the AWS or GCP guides for provider-specific setup instructions.
The internal PostgreSQL option (postgres.enabled: true) is not intended for production use. It lacks high-availability features, automated backups, and enterprise-grade reliability. Always use an external managed PostgreSQL service (AWS RDS, Azure Database, Google Cloud SQL, etc.) for production deployments.
Internal PostgreSQL (Development/Testing Only):

2. Object Storage Configuration

For External S3 (Recommended):
For Azure Blob Storage:
For Google Cloud Storage (GCS):
GCS_IAM_SIGNING: "true" enables Workload Identity-based signing for signed URL generation, which avoids the need to supply a service account key. Requires the platform’s Kubernetes service account to be bound to a GCP service account with Storage Object Admin and Service Account Token Creator roles. See the GCP Integration Guide for IAM setup.
The internal MinIO option (minio.enabled: true) is not intended for production use. Use external S3-compatible storage for production deployments.

3. Secret Management

The chart supports three secret management approaches:

Option A: Direct Secret Values (Simple)

Secrets are base64-encoded automatically. Some secrets like SECRET_KEY_BASE are auto-generated with upgrade persistence using the lookup function if not provided. ArgoCD users must set these values explicitly — see ArgoCD Deployment Guide.
Automatic Pod Restarts: When you update secret values and run helm upgrade, pods automatically restart with a rolling update to pick up the new credentials. This ensures credential rotation is applied without manual intervention or downtime.

4. Ingress and Networking

AWS Application Load Balancer

NGINX Ingress Controller

Application-Level TLS (Self-Signed)

For environments without ingress TLS, enable application-level HTTPS:

5. Authentication Configuration

Local Authentication

Microsoft Entra ID (Azure AD)

ENTRA_ID_CLIENT_ID and ENTRA_ID_TENANT_ID are non-sensitive identifiers and must be placed under envVars:, not secrets:. Only ENTRA_ID_CLIENT_SECRET is a credential and belongs under secrets:.
Setup: You need the Application (client) ID, Directory (tenant) ID, and a client secret from your Azure App Registration. For Azure portal setup steps, see Entra ID SSO.

Okta

OKTA_SITE, OKTA_CLIENT_ID, OKTA_AUTHORIZATION_SERVER, and OKTA_AUDIENCE are non-sensitive configuration identifiers. They must be placed under envVars:, not secrets:. The chart template does not render Okta values from secrets: — placing them there silently excludes them from pod environment variables, causing authentication to fail with no error message referencing the missing keys.
Setup: You need a Client ID, authorization server ID, and audience from an OIDC Web Application integration in the Okta Admin Console. For Okta admin console setup steps, see Okta SSO.

WorkOS

WORKOS_API_KEY is placed under envVars: rather than secrets: due to a known chart template gap — the chart does not render secrets.WORKOS_API_KEY into the pod environment. The key is therefore stored in a ConfigMap rather than a Kubernetes Secret. Verify after install:
WORKOS_COOKIE_PASSWORD must be 32 characters or fewer. Generate one with: openssl rand -base64 32 | cut -c -32It is stored as a plain environment variable (not a Kubernetes Secret) by the chart. Supply it via --set or a gitignored values file to avoid committing it.
For the complete WorkOS Dashboard setup, see WorkOS SSO. Setup: You need a Client ID, AuthKit domain, and API key from the WorkOS Dashboard, plus a generated cookie password for session encryption.

Keycloak

Setup: You need a Client ID, Client Secret, realm name, and Keycloak server URL from an OpenID Connect client configured in the Keycloak Admin Console. For Keycloak realm configuration steps, see Keycloak SSO.

6. Resource Sizing

Production-grade resource defaults are included, but adjust based on your workload:
The default resource requests are conservative. For production workloads, increase requests to ensure reliable scheduling and performance.

7. High Availability Configuration

For production HA deployments:

8. Image Registry Configuration

Using Replicated Proxy (Default)

Private Registry with Simplified Paths

Choosing the right registry override — key distinction:If you only need crew build images in your private registry, set CREW_IMAGE_REGISTRY_OVERRIDE and omit global.imageRegistry and global.imageNamePrefixOverride.
When mirroring images to a private registry like AWS ECR or Azure ACR, use global.imageNamePrefixOverride to simplify image paths:
envVars.CREW_IMAGE_REGISTRY_OVERRIDE is required for crew automation deployments. CrewAI Platform builds crew images internally and pushes them to this registry after each build, so the registry must support both push and pull operations from build and runtime pods.
GCP Artifact Registry: Do NOT use global.imageRegistry for standard GCP/GAR deployments. Setting it to your GAR host redirects all platform image pulls (Redis, BuildKit, Wharf) away from images.crewai.com and causes ImagePullBackOff on every pod. For GCP, use only CREW_IMAGE_REGISTRY_OVERRIDE. See the GCP Integration Guide for the correct configuration.
Supported targets include AWS ECR, Azure Container Registry (ACR), Google Artifact Registry (GAR), and JFrog Artifactory. For canonical requirements, see Requirements. Permission and access checklist:
  • Registry endpoint is reachable from build and runtime pods
  • Credentials grant image push and pull permissions
  • The platform automatically appends /crewai-enterprise; ensure the resulting repository path exists and accepts pushes
For detailed validation behavior and format examples, see envVars.CREW_IMAGE_REGISTRY_OVERRIDE. How it works:
  • Without override: images.crewai.com/proxy/crewai/dockerhub/library/postgres:16
  • With override: 123456789012.dkr.ecr.us-west-2.amazonaws.com/crewai/postgres:16
The imageNamePrefixOverride replaces complex multi-level paths (like proxy/crewai/dockerhub/library/) with a simple prefix. It extracts only the final image name component (e.g., postgres) and applies the override prefix to it. This is not a simple prepend operation - it completely replaces the path structure, making image management in private registries easier. Affected components:
  • Main application, PostgreSQL, MinIO, BuildKit, Redis, Busybox images
  • Environment variables: CONTAINER_REGISTRY_HOSTNAME, AUTOMATION_ECR_REPOSITORY_PREFIX
Complete Example:

Additional Private Registries

Security Best Practices

1. Secret Management

  • Never commit secrets to version control
  • Use external secret stores (AWS Secrets Manager, Azure Key Vault) for production
  • Rotate secrets regularly

2. Network Security

  • Enable TLS for all external endpoints
  • Configure ingress whitelist restrictions
  • Use private subnets for database and internal services
  • Enable CORS with restrictive origin policies

3. RBAC and Service Accounts

4. Database Security

  • Use encrypted connections to database (SSL/TLS)
  • Store database credentials in secret stores
  • Enable audit logging on database

5. BuildKit Security

For enhanced security, enable rootless BuildKit mode to run container builds without privileged containers:
Benefits:
  • No privileged container required for image builds
  • Runs as non-root user with user namespace remapping
  • Reduces attack surface for container build operations
Requirements:
  • Kubernetes nodes must allow seccompProfile: Unconfined and appArmorProfile: Unconfined
  • May not be compatible with restrictive security policies (e.g., GKE Autopilot)
Note: If rootless mode is not compatible with your environment, the chart defaults to standard privileged BuildKit mode.

6. Database Migration Management

The chart implements automatic database migrations via Helm hooks, ensuring schema changes and data migrations are applied safely during installation and upgrades. Migration Process: During Initial Installation (helm install):
  1. After deployment, a setup Job runs automatically
  2. Job waits for PostgreSQL and MinIO availability (when enabled)
  3. Executes bin/rails db:migrate for main database
  4. Executes bin/rails db:migrate:cable for ActionCable database
  5. Executes bin/rails db:seed to populate initial data
  6. Executes bin/rails data:migrate to apply data migrations
  7. Sets up default permissions and syncs feature flags
  8. Job retries up to 10 times on failure
During Upgrades (helm upgrade):
  1. Before each upgrade, a pre-upgrade Job runs automatically
  2. Job waits for PostgreSQL availability (when using internal PostgreSQL)
  3. Executes bin/rails db:migrate for main database
  4. Executes bin/rails db:migrate:cable for ActionCable database
  5. Executes bin/rails data:migrate to apply data migrations
  6. Job retries up to 3 times on failure
  7. Upgrade proceeds only after successful migration
Data migrations (bin/rails data:migrate) are automatically applied during both initial installation and upgrades, ensuring data transformations are kept in sync with schema changes.
Custom Node Placement:
Troubleshooting: View migration job logs:
Check migration job status:

Common Deployment Scenarios

Scenario 1: AWS Production Deployment

Scenario 2: Azure Production Deployment

my-values.yaml
AZURE_CONTAINER_NAME must match the blob container name you created in Azure Blob Storage. If omitted, uploads will fail at runtime.

Scenario 3: GCP Production Deployment (Cloud SQL + GCS + Artifact Registry)

my-values-gcp.yaml
See the GCP Integration Guide for full infrastructure setup.

Scenario 4: Development/Testing Environment