d25d482dc2
CI / Migrate DB (push) Blocked by required conditions
CI / Migrate Dev DB (push) Waiting to run
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Blocked by required conditions
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Blocked by required conditions
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Blocked by required conditions
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Blocked by required conditions
CI / Deploy Trigger.dev (Dev) (push) Blocked by required conditions
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Blocked by required conditions
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Blocked by required conditions
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Blocked by required conditions
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Blocked by required conditions
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Blocked by required conditions
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Blocked by required conditions
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Blocked by required conditions
CI / Check Docs Changes (push) Waiting to run
CI / Process Docs (push) Blocked by required conditions
CI / Create GitHub Release (push) Blocked by required conditions
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Test and Build (push) Waiting to run
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Blocked by required conditions
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Blocked by required conditions
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Blocked by required conditions
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Blocked by required conditions
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Blocked by required conditions
CI / Detect Version (push) Waiting to run
1841 lines
67 KiB
YAML
1841 lines
67 KiB
YAML
# Global configuration
|
|
global:
|
|
# Image registry and pull policy
|
|
imageRegistry: "ghcr.io"
|
|
# Use registry for all images, not just simstudioai/* images
|
|
useRegistryForAllImages: false
|
|
imagePullSecrets: []
|
|
|
|
# Common labels applied to all resources
|
|
commonLabels: {}
|
|
|
|
# Storage class for persistent volumes
|
|
storageClass: ""
|
|
|
|
# Main Sim application configuration
|
|
app:
|
|
# Enable/disable the main application
|
|
enabled: true
|
|
|
|
# Image configuration
|
|
image:
|
|
repository: simstudioai/simstudio
|
|
# tag defaults to Chart.AppVersion. Override with a release tag (e.g. "0.6.73") or pin via image.digest.
|
|
tag: ""
|
|
# Optional image digest pin: "sha256:..." — when set, overrides tag.
|
|
digest: ""
|
|
pullPolicy: IfNotPresent
|
|
|
|
# Number of replicas
|
|
replicaCount: 1
|
|
|
|
# Resource limits and requests
|
|
resources:
|
|
limits:
|
|
memory: "8Gi"
|
|
cpu: "2000m"
|
|
requests:
|
|
memory: "4Gi"
|
|
cpu: "1000m"
|
|
|
|
# Node selector for pod scheduling (leave empty to allow scheduling on any node)
|
|
nodeSelector: {}
|
|
|
|
# Topology spread constraints for app pods (HA across zones / nodes).
|
|
# Each entry must include its own labelSelector.
|
|
topologySpreadConstraints: []
|
|
|
|
# Pod security context
|
|
podSecurityContext:
|
|
fsGroup: 1001
|
|
|
|
# Container security context
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 1001
|
|
|
|
# Secret management configuration
|
|
# Use this to reference pre-existing Kubernetes secrets instead of defining values directly
|
|
# This enables integration with External Secrets Operator, HashiCorp Vault, Azure Key Vault, etc.
|
|
secrets:
|
|
existingSecret:
|
|
# Set to true to use an existing secret instead of creating one from values
|
|
enabled: false
|
|
# Name of the existing Kubernetes secret containing app credentials
|
|
name: ""
|
|
# Key mappings - specify the key names in your existing secret
|
|
# Only needed if your secret uses different key names than the defaults
|
|
keys:
|
|
BETTER_AUTH_SECRET: "BETTER_AUTH_SECRET"
|
|
ENCRYPTION_KEY: "ENCRYPTION_KEY"
|
|
INTERNAL_API_SECRET: "INTERNAL_API_SECRET"
|
|
CRON_SECRET: "CRON_SECRET"
|
|
API_ENCRYPTION_KEY: "API_ENCRYPTION_KEY"
|
|
REDIS_URL: "REDIS_URL"
|
|
|
|
# Environment variables
|
|
env:
|
|
# Application URLs — set NEXT_PUBLIC_APP_URL / BETTER_AUTH_URL to your public origin
|
|
# (e.g. https://sim.example.com). Defaults to http://localhost:3000 via app.envDefaults
|
|
# for local installs; override here (or via --set) for production. Set values here go
|
|
# into the chart-managed Secret and take precedence over envDefaults at runtime.
|
|
NEXT_PUBLIC_APP_URL: ""
|
|
BETTER_AUTH_URL: ""
|
|
INTERNAL_API_BASE_URL: "" # Optional server-side internal base URL for /api self-calls (include http:// or https://); falls back to NEXT_PUBLIC_APP_URL when empty
|
|
# TRUSTED_ORIGINS: comma-separated extra public origins to trust for auth (e.g. apex+www, alias hostnames).
|
|
# Merged into Better Auth `trustedOrigins` alongside NEXT_PUBLIC_APP_URL. Leave empty when serving from a single origin.
|
|
TRUSTED_ORIGINS: ""
|
|
# SOCKET_SERVER_URL: Auto-detected when realtime.enabled=true (uses internal service)
|
|
# NEXT_PUBLIC_SOCKET_URL: public WebSocket URL for browsers. Leave empty to default to the
|
|
# page's own origin (assumes the ingress/reverse proxy routes /socket.io to the realtime service).
|
|
# Set explicitly only when realtime is on a separate host:port from the app (e.g. wss://socket.example.com).
|
|
NEXT_PUBLIC_SOCKET_URL: ""
|
|
|
|
# Telemetry & Monitoring
|
|
TELEMETRY_ENDPOINT: "" # OTLP endpoint for traces/logs (e.g., "https://otlp-collector:4318/v1/traces")
|
|
|
|
# Authentication and encryption secrets (REQUIRED for production)
|
|
# Generate secure 32-character secrets using: openssl rand -hex 32
|
|
BETTER_AUTH_SECRET: "" # REQUIRED - set via --set flag or external secret manager
|
|
ENCRYPTION_KEY: "" # REQUIRED - set via --set flag or external secret manager
|
|
INTERNAL_API_SECRET: "" # REQUIRED - set via --set flag or external secret manager, used for internal service-to-service authentication
|
|
|
|
# Optional: Scheduled Jobs Authentication
|
|
# Generate using: openssl rand -hex 32
|
|
CRON_SECRET: "" # OPTIONAL - required only if cronjobs.enabled=true, authenticates scheduled job requests
|
|
|
|
# Optional: API Key Encryption (RECOMMENDED for production)
|
|
# Generate with: openssl rand -hex 32 (produces the required 64-hex-char / 32-byte value).
|
|
API_ENCRYPTION_KEY: "" # OPTIONAL - encrypts API keys at rest; if unset, keys are stored in plain text
|
|
REDIS_URL: "" # OPTIONAL - Redis connection string for caching/sessions; can also come from app secret or External Secrets
|
|
|
|
# Email & Communication
|
|
# Configure one provider — the mailer auto-detects in priority order:
|
|
# Resend → AWS SES → SMTP → Azure Communication Services.
|
|
EMAIL_VERIFICATION_ENABLED: "" # Set to "true" to enable email verification for user registration and login (default "false" via envDefaults)
|
|
RESEND_API_KEY: "" # Resend API key for transactional emails
|
|
FROM_EMAIL_ADDRESS: "" # Complete from address (e.g., "Sim <noreply@domain.com>" or "DoNotReply@domain.com")
|
|
EMAIL_DOMAIN: "" # Domain for sending emails (fallback when FROM_EMAIL_ADDRESS not set)
|
|
AWS_SES_REGION: "" # AWS region for SES (e.g., "us-east-1"); credentials resolved via the standard AWS provider chain (env, IRSA, instance profile)
|
|
AZURE_ACS_CONNECTION_STRING: "" # Azure Communication Services connection string (email provider — used when Resend/SES/SMTP are not configured)
|
|
SMTP_HOST: "" # SMTP server hostname (alternative to Resend/SES)
|
|
SMTP_PORT: "" # SMTP server port (465 for TLS, 587 for STARTTLS, 25 for plain)
|
|
SMTP_USER: "" # SMTP username (optional — omit for unauthenticated relays like MailHog)
|
|
SMTP_PASS: "" # SMTP password (optional — omit for unauthenticated relays)
|
|
SMTP_SECURE: "" # Set to "true" to force TLS on connect; defaults to true when SMTP_PORT=465
|
|
|
|
|
|
# OAuth Integration Credentials (leave empty if not using)
|
|
GOOGLE_CLIENT_ID: "" # Google OAuth client ID
|
|
GOOGLE_CLIENT_SECRET: "" # Google OAuth client secret
|
|
GITHUB_CLIENT_ID: "" # GitHub OAuth client ID
|
|
GITHUB_CLIENT_SECRET: "" # GitHub OAuth client secret
|
|
DISABLE_GOOGLE_AUTH: "" # Set to "true" to hide Google OAuth login
|
|
DISABLE_GITHUB_AUTH: "" # Set to "true" to hide GitHub OAuth login
|
|
|
|
# Google Vertex AI Configuration
|
|
VERTEX_PROJECT: "" # Google Cloud project ID for Vertex AI
|
|
VERTEX_LOCATION: "" # Google Cloud region for Vertex AI (default "us-central1" via envDefaults)
|
|
|
|
# Azure OpenAI Configuration (leave empty if not using Azure OpenAI)
|
|
AZURE_OPENAI_ENDPOINT: "" # Azure OpenAI service endpoint (e.g., https://your-resource.openai.azure.com)
|
|
AZURE_OPENAI_API_KEY: "" # Azure OpenAI API key
|
|
AZURE_OPENAI_API_VERSION: "" # Azure OpenAI API version (e.g., 2024-07-01-preview)
|
|
|
|
# Azure Anthropic Configuration (leave empty if not using Azure Anthropic via AI Foundry)
|
|
AZURE_ANTHROPIC_ENDPOINT: "" # Azure AI Foundry endpoint for Anthropic models
|
|
AZURE_ANTHROPIC_API_KEY: "" # Azure Anthropic API key
|
|
AZURE_ANTHROPIC_API_VERSION: "" # Azure Anthropic API version (e.g., 2023-06-01)
|
|
KB_OPENAI_MODEL_NAME: "" # Azure deployment name serving the configured KB embedding model (used only when AZURE_OPENAI_* credentials are set)
|
|
WAND_OPENAI_MODEL_NAME: "" # Wand generation model deployment name (works with both regular OpenAI and Azure OpenAI)
|
|
|
|
# Azure Mistral OCR Configuration (leave empty if not using Azure-hosted OCR for document processing)
|
|
OCR_AZURE_ENDPOINT: "" # Azure Mistral OCR service endpoint
|
|
OCR_AZURE_MODEL_NAME: "" # Azure Mistral OCR model name
|
|
OCR_AZURE_API_KEY: "" # Azure Mistral OCR API key
|
|
|
|
# AI Provider API Keys (leave empty if not using)
|
|
OPENAI_API_KEY: "" # Primary OpenAI API key
|
|
OPENAI_API_KEY_1: "" # Additional OpenAI API key for load balancing
|
|
OPENAI_API_KEY_2: "" # Additional OpenAI API key for load balancing
|
|
OPENAI_API_KEY_3: "" # Additional OpenAI API key for load balancing
|
|
MISTRAL_API_KEY: "" # Mistral AI API key
|
|
FIREWORKS_API_KEY: "" # Fireworks AI API key (for hosted model access)
|
|
ANTHROPIC_API_KEY_1: "" # Primary Anthropic Claude API key
|
|
ANTHROPIC_API_KEY_2: "" # Additional Anthropic API key for load balancing
|
|
ANTHROPIC_API_KEY_3: "" # Additional Anthropic API key for load balancing
|
|
OLLAMA_URL: "" # Ollama local LLM server URL
|
|
PII_URL: "" # Presidio PII service URL; auto-computed when pii.enabled, override here otherwise
|
|
ELEVENLABS_API_KEY: "" # ElevenLabs API key for text-to-speech in deployed chat
|
|
|
|
# UI Branding & Whitelabeling Configuration
|
|
NEXT_PUBLIC_BRAND_NAME: "" # Custom brand name (default "Sim" via envDefaults)
|
|
NEXT_PUBLIC_BRAND_LOGO_URL: "" # Custom logo URL — square icon, shown in collapsed sidebar
|
|
NEXT_PUBLIC_BRAND_WORDMARK_URL: "" # Custom wordmark URL — wide image, shown in expanded sidebar
|
|
NEXT_PUBLIC_BRAND_FAVICON_URL: "" # Custom favicon URL (leave empty for default)
|
|
NEXT_PUBLIC_BRAND_PRIMARY_COLOR: "" # Primary brand color (hex, e.g., "#701a75")
|
|
NEXT_PUBLIC_BRAND_ACCENT_COLOR: "" # Accent color (hex, e.g., "#9333ea")
|
|
NEXT_PUBLIC_BRAND_BACKGROUND_COLOR: "" # Background color (hex, e.g., "#ffffff")
|
|
NEXT_PUBLIC_CUSTOM_CSS_URL: "" # Custom stylesheet URL (leave empty for none)
|
|
NEXT_PUBLIC_SUPPORT_EMAIL: "" # Support email address (default "help@sim.ai" via envDefaults)
|
|
NEXT_PUBLIC_DOCUMENTATION_URL: "" # Documentation URL (leave empty for none)
|
|
NEXT_PUBLIC_TERMS_URL: "" # Terms of service URL (leave empty for none)
|
|
NEXT_PUBLIC_PRIVACY_URL: "" # Privacy policy URL (leave empty for none)
|
|
|
|
# Registration Control
|
|
DISABLE_REGISTRATION: "" # Set to "true" to disable new user signups
|
|
EMAIL_PASSWORD_SIGNUP_ENABLED: "" # Set to "false" to disable email/password login (SSO-only mode, server-side enforcement)
|
|
NEXT_PUBLIC_EMAIL_PASSWORD_SIGNUP_ENABLED: "" # Set to "false" to hide email/password login form (UI-side)
|
|
|
|
# Bot Protection (Cloudflare Turnstile)
|
|
TURNSTILE_SECRET_KEY: "" # Cloudflare Turnstile secret key (leave empty to disable captcha)
|
|
NEXT_PUBLIC_TURNSTILE_SITE_KEY: "" # Cloudflare Turnstile site key (leave empty to disable captcha)
|
|
|
|
# Access Control (leave empty if not restricting login)
|
|
ALLOWED_LOGIN_EMAILS: "" # Comma-separated list of allowed email addresses for login
|
|
ALLOWED_LOGIN_DOMAINS: "" # Comma-separated list of allowed email domains for login
|
|
|
|
# Admin API Configuration
|
|
ADMIN_API_KEY: "" # Admin API key for organization/user management (generate with: openssl rand -hex 32)
|
|
|
|
# Organizations & Permission Groups (defaults to "false" via envDefaults — set "true" here to enable)
|
|
ACCESS_CONTROL_ENABLED: "" # Enable permission groups feature ("true" to enable)
|
|
ORGANIZATIONS_ENABLED: "" # Enable organizations feature ("true" to enable)
|
|
NEXT_PUBLIC_ACCESS_CONTROL_ENABLED: "" # Show permission groups UI ("true" to enable)
|
|
NEXT_PUBLIC_ORGANIZATIONS_ENABLED: "" # Show organizations UI ("true" to enable)
|
|
|
|
# LLM Provider/Model Restrictions (leave empty if not restricting)
|
|
BLACKLISTED_PROVIDERS: "" # Comma-separated provider IDs to hide from UI (e.g., "openai,anthropic,google")
|
|
BLACKLISTED_MODELS: "" # Comma-separated model names/prefixes to hide (e.g., "gpt-4,claude-*")
|
|
ALLOWED_MCP_DOMAINS: "" # Comma-separated domains for MCP servers (e.g., "internal.company.com,mcp.example.org"). Empty = all allowed.
|
|
|
|
# Integration/Block Restrictions (leave empty if not restricting)
|
|
ALLOWED_INTEGRATIONS: "" # Comma-separated block types to allow (e.g., "slack,github,agent"). Empty = all allowed.
|
|
|
|
# Invitation Control
|
|
DISABLE_INVITATIONS: "" # Set to "true" to disable workspace invitations globally
|
|
NEXT_PUBLIC_DISABLE_INVITATIONS: "" # Set to "true" to hide invitation UI elements
|
|
|
|
# Public API Access Control
|
|
DISABLE_PUBLIC_API: "" # Set to "true" to disable public API toggle globally
|
|
NEXT_PUBLIC_DISABLE_PUBLIC_API: "" # Set to "true" to hide public API toggle in UI
|
|
|
|
# SSO Configuration (Enterprise Single Sign-On)
|
|
# Set to "true" AFTER running the SSO registration script
|
|
SSO_ENABLED: "" # Enable SSO authentication ("true" to enable)
|
|
NEXT_PUBLIC_SSO_ENABLED: "" # Show SSO login button in UI ("true" to enable)
|
|
# SSO_TRUSTED_PROVIDER_IDS: comma-separated SSO provider IDs to trust for automatic account linking when a
|
|
# user signs in via SSO and an account with the same email already exists. Only needed for IdPs that do NOT
|
|
# assert email_verified (trustEmailVerified already handles those that do). Resolved at startup — restart after editing.
|
|
SSO_TRUSTED_PROVIDER_IDS: ""
|
|
|
|
# Enterprise Feature Overrides (self-hosted)
|
|
INBOX_ENABLED: "" # Enable Sim Mailer on self-hosted ("true" to enable)
|
|
NEXT_PUBLIC_INBOX_ENABLED: "" # Show Sim Mailer settings page ("true" to enable)
|
|
WHITELABELING_ENABLED: "" # Enable whitelabeling on self-hosted ("true" to enable)
|
|
NEXT_PUBLIC_WHITELABELING_ENABLED: "" # Show whitelabeling settings page ("true" to enable)
|
|
AUDIT_LOGS_ENABLED: "" # Enable audit logs on self-hosted ("true" to enable)
|
|
NEXT_PUBLIC_AUDIT_LOGS_ENABLED: "" # Show audit logs settings page ("true" to enable)
|
|
DATA_DRAINS_ENABLED: "" # Enable data drains on self-hosted ("true" to enable)
|
|
NEXT_PUBLIC_DATA_DRAINS_ENABLED: "" # Show data drains settings page ("true" to enable)
|
|
|
|
# AWS Bedrock Credential Mode
|
|
# Set to "true" when the deployment uses AWS default credential chain (IAM roles, instance
|
|
# profiles, ECS task roles, IRSA, etc.) instead of explicit access key/secret per workflow.
|
|
# When enabled, the AWS Access Key ID and Secret fields are hidden in the Agent block UI.
|
|
NEXT_PUBLIC_BEDROCK_DEFAULT_CREDENTIALS: "" # Set to "true" to hide Bedrock credential fields
|
|
|
|
# Azure Provider Credential Mode
|
|
# Set to "true" when AZURE_OPENAI_ENDPOINT/API_KEY (and/or AZURE_ANTHROPIC_*) are configured
|
|
# server-side. When enabled, the Azure endpoint, API key, and API version fields are hidden
|
|
# in the Agent block UI — users just pick an Azure model and run.
|
|
NEXT_PUBLIC_AZURE_CONFIGURED: "" # Set to "true" to hide Azure credential fields
|
|
|
|
# Cohere Reranker (Knowledge block)
|
|
# Set COHERE_API_KEY (or COHERE_API_KEY_1/2/3 for rotation) and NEXT_PUBLIC_COHERE_CONFIGURED=true
|
|
# to pre-configure the Cohere reranker server-side. When configured, the Cohere API Key field is
|
|
# hidden in the Knowledge block UI.
|
|
NEXT_PUBLIC_COHERE_CONFIGURED: "" # Set to "true" to hide the Cohere API Key field on the Knowledge block
|
|
|
|
# AWS S3 Cloud Storage Configuration (optional - for file storage)
|
|
# If configured, files will be stored in S3 instead of local storage
|
|
AWS_REGION: "" # AWS region (e.g., "us-east-1")
|
|
AWS_ACCESS_KEY_ID: "" # AWS access key ID
|
|
AWS_SECRET_ACCESS_KEY: "" # AWS secret access key
|
|
S3_BUCKET_NAME: "" # S3 bucket for workspace files
|
|
S3_KB_BUCKET_NAME: "" # S3 bucket for knowledge base files
|
|
S3_EXECUTION_FILES_BUCKET_NAME: "" # S3 bucket for workflow execution files
|
|
S3_CHAT_BUCKET_NAME: "" # S3 bucket for deployed chat files
|
|
S3_COPILOT_BUCKET_NAME: "" # S3 bucket for copilot files
|
|
S3_PROFILE_PICTURES_BUCKET_NAME: "" # S3 bucket for user profile pictures
|
|
S3_OG_IMAGES_BUCKET_NAME: "" # S3 bucket for OpenGraph preview images
|
|
S3_WORKSPACE_LOGOS_BUCKET_NAME: "" # S3 bucket for workspace logos
|
|
S3_ENDPOINT: "" # Custom endpoint for S3-compatible storage (Cloudflare R2, MinIO, Backblaze B2). Leave empty for AWS S3
|
|
S3_FORCE_PATH_STYLE: "" # Set to "true" for path-style addressing (MinIO/Ceph RGW). Leave empty for AWS S3 and R2
|
|
|
|
# Azure Blob Storage Configuration (optional - for file storage)
|
|
# If configured, files will be stored in Azure Blob instead of local storage
|
|
# Note: Azure Blob takes precedence over S3 if both are configured
|
|
AZURE_ACCOUNT_NAME: "" # Azure storage account name
|
|
AZURE_ACCOUNT_KEY: "" # Azure storage account key
|
|
AZURE_CONNECTION_STRING: "" # Azure connection string (alternative to account name/key)
|
|
AZURE_STORAGE_CONTAINER_NAME: "" # Azure container for workspace files
|
|
AZURE_STORAGE_KB_CONTAINER_NAME: "" # Azure container for knowledge base files
|
|
AZURE_STORAGE_EXECUTION_FILES_CONTAINER_NAME: "" # Azure container for workflow execution files
|
|
AZURE_STORAGE_CHAT_CONTAINER_NAME: "" # Azure container for deployed chat files
|
|
AZURE_STORAGE_COPILOT_CONTAINER_NAME: "" # Azure container for copilot files
|
|
AZURE_STORAGE_PROFILE_PICTURES_CONTAINER_NAME: "" # Azure container for user profile pictures
|
|
AZURE_STORAGE_OG_IMAGES_CONTAINER_NAME: "" # Azure container for OpenGraph preview images
|
|
AZURE_STORAGE_WORKSPACE_LOGOS_CONTAINER_NAME: "" # Azure container for workspace logos
|
|
|
|
# Operational tunables shipped with the chart. These are rendered as inline `env:` on the
|
|
# app container — NOT written into the chart-managed Secret and NOT required to be mapped
|
|
# when externalSecrets.enabled=true. Override any key by setting `app.envDefaults.KEY` in
|
|
# your values file. Move a key into `app.env` above only if it must be treated as secret.
|
|
envDefaults:
|
|
# Application URLs (override in app.env or app.envDefaults for production)
|
|
NEXT_PUBLIC_APP_URL: "http://localhost:3000"
|
|
BETTER_AUTH_URL: "http://localhost:3000"
|
|
|
|
# Node environment
|
|
NODE_ENV: "production"
|
|
NEXT_TELEMETRY_DISABLED: "1"
|
|
|
|
# Email defaults
|
|
EMAIL_VERIFICATION_ENABLED: "false"
|
|
|
|
# Vertex AI defaults
|
|
VERTEX_LOCATION: "us-central1"
|
|
|
|
# Branding defaults
|
|
NEXT_PUBLIC_BRAND_NAME: "Sim"
|
|
NEXT_PUBLIC_SUPPORT_EMAIL: "help@sim.ai"
|
|
|
|
# Feature flags (default off — set "true" in app.env or app.envDefaults to enable)
|
|
ACCESS_CONTROL_ENABLED: "false"
|
|
ORGANIZATIONS_ENABLED: "false"
|
|
NEXT_PUBLIC_ACCESS_CONTROL_ENABLED: "false"
|
|
NEXT_PUBLIC_ORGANIZATIONS_ENABLED: "false"
|
|
|
|
# Admission Gate
|
|
ADMISSION_GATE_MAX_INFLIGHT: "500" # Max concurrent in-flight execution requests per pod
|
|
|
|
# Rate Limiting (per minute)
|
|
RATE_LIMIT_WINDOW_MS: "60000" # Rate limit window duration (1 minute)
|
|
RATE_LIMIT_FREE_SYNC: "50" # Sync API executions per minute
|
|
RATE_LIMIT_FREE_ASYNC: "200" # Async API executions per minute
|
|
|
|
# Execution Timeouts (seconds) — sync timeouts apply to synchronous API calls
|
|
EXECUTION_TIMEOUT_FREE: "300" # Free tier sync timeout (5 minutes)
|
|
EXECUTION_TIMEOUT_PRO: "3000" # Pro tier sync timeout (50 minutes)
|
|
EXECUTION_TIMEOUT_TEAM: "3000" # Team tier sync timeout (50 minutes)
|
|
EXECUTION_TIMEOUT_ENTERPRISE: "3000" # Enterprise tier sync timeout (50 minutes)
|
|
# Async timeouts apply to async/background job executions
|
|
EXECUTION_TIMEOUT_ASYNC_FREE: "5400" # Free tier async timeout (90 minutes)
|
|
EXECUTION_TIMEOUT_ASYNC_PRO: "5400" # Pro tier async timeout (90 minutes)
|
|
EXECUTION_TIMEOUT_ASYNC_TEAM: "5400" # Team tier async timeout (90 minutes)
|
|
EXECUTION_TIMEOUT_ASYNC_ENTERPRISE: "5400" # Enterprise tier async timeout (90 minutes)
|
|
|
|
# Table Feature Limits (per workspace, per plan)
|
|
FREE_TABLES_LIMIT: "3" # Max user tables per workspace on free tier
|
|
FREE_TABLE_ROWS_LIMIT: "1000" # Max rows per table on free tier
|
|
PRO_TABLES_LIMIT: "25" # Max user tables per workspace on pro tier
|
|
PRO_TABLE_ROWS_LIMIT: "5000" # Max rows per table on pro tier
|
|
TEAM_TABLES_LIMIT: "100" # Max user tables per workspace on team tier
|
|
TEAM_TABLE_ROWS_LIMIT: "10000" # Max rows per table on team tier
|
|
ENTERPRISE_TABLES_LIMIT: "10000" # Max user tables per workspace on enterprise tier
|
|
ENTERPRISE_TABLE_ROWS_LIMIT: "1000000" # Max rows per table on enterprise tier
|
|
|
|
# Isolated-VM Worker Pool
|
|
IVM_POOL_SIZE: "4" # Max worker processes in pool
|
|
IVM_MAX_CONCURRENT: "10000" # Max concurrent executions globally
|
|
IVM_MAX_PER_WORKER: "2500" # Max concurrent executions per worker
|
|
IVM_WORKER_IDLE_TIMEOUT_MS: "60000" # Worker idle cleanup timeout (ms)
|
|
IVM_QUEUE_TIMEOUT_MS: "300000" # Max queue wait before rejection (ms)
|
|
IVM_MAX_QUEUE_SIZE: "10000" # Max queued executions globally
|
|
IVM_MAX_ACTIVE_PER_OWNER: "200" # Max concurrent executions per user
|
|
IVM_MAX_QUEUED_PER_OWNER: "2000" # Max queued executions per user
|
|
IVM_MAX_OWNER_WEIGHT: "5" # Max scheduling weight per user
|
|
IVM_DISTRIBUTED_MAX_INFLIGHT_PER_OWNER: "2200" # Max in-flight per user across instances (Redis)
|
|
IVM_DISTRIBUTED_LEASE_MIN_TTL_MS: "120000" # Min distributed lease TTL (ms)
|
|
IVM_MAX_FETCH_RESPONSE_BYTES: "8388608" # Max fetch response size (8MB)
|
|
IVM_MAX_FETCH_RESPONSE_CHARS: "4000000" # Max fetch response chars
|
|
IVM_MAX_FETCH_URL_LENGTH: "8192" # Max fetch URL length
|
|
IVM_MAX_FETCH_OPTIONS_JSON_CHARS: "262144" # Max fetch options payload (256KB)
|
|
IVM_MAX_STDOUT_CHARS: "200000" # Max stdout capture per execution
|
|
|
|
# Service configuration
|
|
service:
|
|
type: ClusterIP
|
|
port: 3000
|
|
targetPort: 3000
|
|
|
|
# Health checks
|
|
# startupProbe shields a slow Next.js cold start (large bundle, 4Gi memory limits) from
|
|
# liveness restarts. Once it succeeds, liveness + readiness take over. Total cold-start
|
|
# budget: failureThreshold * periodSeconds = 60 * 5s = 300s (5 minutes).
|
|
startupProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 3000
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 5
|
|
timeoutSeconds: 3
|
|
failureThreshold: 60
|
|
|
|
# Liveness: lenient — only restart on true deadlock. failureThreshold * periodSeconds = 180s.
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 3000
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
timeoutSeconds: 5
|
|
failureThreshold: 6
|
|
|
|
# Readiness: fast — shift traffic in/out within ~30s of state change.
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 3000
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
timeoutSeconds: 3
|
|
failureThreshold: 3
|
|
|
|
# Additional volumes for app deployment (e.g., branding assets, custom configs)
|
|
extraVolumes: []
|
|
extraVolumeMounts: []
|
|
|
|
# Realtime socket server configuration
|
|
realtime:
|
|
# Enable/disable the realtime service
|
|
enabled: true
|
|
|
|
# Image configuration
|
|
image:
|
|
repository: simstudioai/realtime
|
|
# tag defaults to Chart.AppVersion. Override with a release tag or pin via image.digest.
|
|
tag: ""
|
|
digest: ""
|
|
pullPolicy: IfNotPresent
|
|
|
|
# Number of replicas
|
|
replicaCount: 1
|
|
|
|
# Resource limits and requests
|
|
resources:
|
|
limits:
|
|
memory: "1Gi"
|
|
cpu: "500m"
|
|
requests:
|
|
memory: "512Mi"
|
|
cpu: "250m"
|
|
|
|
# Node selector for pod scheduling (leave empty to allow scheduling on any node)
|
|
nodeSelector: {}
|
|
|
|
# Topology spread constraints for realtime pods (HA across zones / nodes).
|
|
# Each entry must include its own labelSelector.
|
|
topologySpreadConstraints: []
|
|
|
|
# Pod security context
|
|
podSecurityContext:
|
|
fsGroup: 1001
|
|
|
|
# Container security context
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 1001
|
|
|
|
# Environment variables — Secret-bound. See `envDefaults` below for chart-shipped defaults.
|
|
env:
|
|
# Application URLs — must mirror the public origin used by the main app.
|
|
# Defaults to http://localhost:3000 via envDefaults; override here for production.
|
|
NEXT_PUBLIC_APP_URL: ""
|
|
BETTER_AUTH_URL: ""
|
|
|
|
# Authentication secret (REQUIRED for production)
|
|
# Must match the BETTER_AUTH_SECRET value from the main app configuration
|
|
BETTER_AUTH_SECRET: "" # REQUIRED - set via --set flag or external secret manager
|
|
|
|
# Cross-Origin Resource Sharing (CORS) allowed origins for the realtime service.
|
|
# Set to the same public origin(s) as the main app (comma-separated). The realtime
|
|
# service rejects WebSocket upgrades from origins not in this list.
|
|
# Defaults to http://localhost:3000 via envDefaults; override here for production.
|
|
ALLOWED_ORIGINS: ""
|
|
|
|
# Operational defaults shipped with the chart. Rendered as inline `env:` on the realtime
|
|
# container (NOT written into the Secret, NOT required in externalSecrets.remoteRefs).
|
|
# User-set values in `realtime.env` above take precedence.
|
|
envDefaults:
|
|
NEXT_PUBLIC_APP_URL: "http://localhost:3000"
|
|
BETTER_AUTH_URL: "http://localhost:3000"
|
|
ALLOWED_ORIGINS: "http://localhost:3000"
|
|
NODE_ENV: "production"
|
|
|
|
# Service configuration
|
|
service:
|
|
type: ClusterIP
|
|
port: 3002
|
|
targetPort: 3002
|
|
|
|
# Health checks
|
|
# Startup probe absorbs cold-start time. Total budget: 30 * 5s = 150s.
|
|
startupProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 3002
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 5
|
|
timeoutSeconds: 3
|
|
failureThreshold: 30
|
|
|
|
# Liveness: lenient. failureThreshold * periodSeconds = 180s.
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 3002
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
timeoutSeconds: 5
|
|
failureThreshold: 6
|
|
|
|
# Readiness: fast.
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 3002
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
timeoutSeconds: 3
|
|
failureThreshold: 3
|
|
|
|
# Additional volumes for realtime deployment
|
|
extraVolumes: []
|
|
extraVolumeMounts: []
|
|
|
|
# Database migrations job configuration
|
|
migrations:
|
|
# Enable/disable migrations job
|
|
enabled: true
|
|
|
|
# Image configuration
|
|
image:
|
|
repository: simstudioai/migrations
|
|
# tag defaults to Chart.AppVersion. Override with a release tag or pin via image.digest.
|
|
tag: ""
|
|
digest: ""
|
|
pullPolicy: IfNotPresent
|
|
|
|
# Resource limits and requests
|
|
resources:
|
|
limits:
|
|
memory: "1Gi"
|
|
requests:
|
|
memory: "512Mi"
|
|
cpu: "100m"
|
|
|
|
# Pod security context
|
|
podSecurityContext:
|
|
fsGroup: 1001
|
|
|
|
# Container security context
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 1001
|
|
|
|
# PostgreSQL database configuration
|
|
postgresql:
|
|
# Enable/disable internal PostgreSQL deployment
|
|
enabled: true
|
|
|
|
# Image configuration
|
|
image:
|
|
repository: pgvector/pgvector
|
|
tag: pg17
|
|
pullPolicy: IfNotPresent
|
|
|
|
# Authentication configuration
|
|
auth:
|
|
username: postgres
|
|
password: "" # REQUIRED - set via --set flag or external secret manager
|
|
database: sim
|
|
# Use an existing secret for PostgreSQL credentials
|
|
# This enables integration with External Secrets Operator, HashiCorp Vault, etc.
|
|
existingSecret:
|
|
enabled: false
|
|
name: "" # Name of existing Kubernetes secret
|
|
passwordKey: "POSTGRES_PASSWORD" # Key in the secret containing the password
|
|
|
|
# Node selector for database pod scheduling (leave empty to allow scheduling on any node)
|
|
nodeSelector: {}
|
|
|
|
# Resource limits and requests
|
|
resources:
|
|
limits:
|
|
memory: "2Gi"
|
|
requests:
|
|
memory: "1Gi"
|
|
cpu: "500m"
|
|
|
|
# Pod security context
|
|
# PostgreSQL image's `postgres` user is uid/gid 999.
|
|
podSecurityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 999
|
|
runAsGroup: 999
|
|
fsGroup: 999
|
|
|
|
# Container security context
|
|
# readOnlyRootFilesystem is intentionally false — Postgres writes to /var/lib/postgresql/data
|
|
# (mounted from PVC) and needs to manage its own data directory.
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 999
|
|
runAsGroup: 999
|
|
|
|
# Persistence configuration
|
|
persistence:
|
|
enabled: true
|
|
storageClass: ""
|
|
size: 10Gi
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
|
|
# SSL/TLS configuration (enable for production deployments with certificates)
|
|
# Requires cert-manager to be installed in the cluster
|
|
tls:
|
|
enabled: false
|
|
certificatesSecret: postgres-tls-secret
|
|
# Certificate configuration (only used if enabled)
|
|
duration: "87600h" # 10 years (default)
|
|
renewBefore: "2160h" # Renew 90 days before expiry (default)
|
|
rotationPolicy: "" # Set to "Always" to rotate private key on renewal (recommended for security)
|
|
privateKey:
|
|
algorithm: RSA # RSA or ECDSA
|
|
size: 4096 # Key size in bits
|
|
# Issuer reference (REQUIRED if tls.enabled is true)
|
|
# By default, references the CA issuer created by certManager.caIssuer
|
|
# Make sure certManager.enabled is true, or provide your own issuer
|
|
issuerRef:
|
|
name: sim-ca-issuer # Name of your cert-manager Issuer/ClusterIssuer
|
|
kind: ClusterIssuer # ClusterIssuer or Issuer
|
|
group: "" # Optional: cert-manager.io (leave empty for default)
|
|
# Additional DNS names (optional)
|
|
additionalDnsNames: []
|
|
# Example:
|
|
# additionalDnsNames:
|
|
# - postgres.example.com
|
|
# - db.example.com
|
|
|
|
# PostgreSQL configuration
|
|
config:
|
|
maxConnections: 1000
|
|
sharedBuffers: "1280MB"
|
|
maxWalSize: "4GB"
|
|
minWalSize: "80MB"
|
|
|
|
# Service configuration
|
|
service:
|
|
type: ClusterIP
|
|
port: 5432
|
|
targetPort: 5432
|
|
|
|
# Health checks
|
|
# startupProbe shields liveness from slow first-boot scenarios (pgvector
|
|
# extension init, WAL replay after a crash on a large data dir). Gives
|
|
# postgres up to 150s (30 * 5s) to become ready before liveness takes over.
|
|
startupProbe:
|
|
exec:
|
|
command: ["pg_isready", "-U", "postgres", "-d", "sim"]
|
|
periodSeconds: 5
|
|
failureThreshold: 30
|
|
timeoutSeconds: 5
|
|
|
|
livenessProbe:
|
|
exec:
|
|
command: ["pg_isready", "-U", "postgres", "-d", "sim"]
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 5
|
|
|
|
readinessProbe:
|
|
exec:
|
|
command: ["pg_isready", "-U", "postgres", "-d", "sim"]
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 3
|
|
|
|
# External database configuration (use when connecting to managed database services)
|
|
externalDatabase:
|
|
# Enable to use an external database instead of the internal PostgreSQL instance
|
|
enabled: false
|
|
|
|
# Database connection details
|
|
host: "external-db.example.com"
|
|
port: 5432
|
|
username: postgres
|
|
password: ""
|
|
database: sim
|
|
|
|
# SSL configuration
|
|
sslMode: require
|
|
|
|
# Use an existing secret for external database credentials
|
|
# This enables integration with External Secrets Operator, HashiCorp Vault, etc.
|
|
existingSecret:
|
|
enabled: false
|
|
name: "" # Name of existing Kubernetes secret
|
|
passwordKey: "EXTERNAL_DB_PASSWORD" # Key in the secret containing the password
|
|
|
|
# Ollama local AI models configuration
|
|
ollama:
|
|
# Enable/disable Ollama deployment
|
|
enabled: false
|
|
|
|
# Image configuration
|
|
image:
|
|
repository: ollama/ollama
|
|
# Pinned to a stable release rather than "latest" to keep deployments reproducible.
|
|
# 0.23.2 is the latest stable Ollama as of May 2026
|
|
# (https://github.com/ollama/ollama/releases/tag/v0.23.2).
|
|
tag: "0.23.2"
|
|
digest: ""
|
|
pullPolicy: IfNotPresent
|
|
|
|
# Number of replicas
|
|
replicaCount: 1
|
|
|
|
# GPU configuration
|
|
gpu:
|
|
enabled: false
|
|
count: 1
|
|
# GPU sharing strategy: "mig" (Multi-Instance GPU) or "time-slicing"
|
|
# - mig: Hardware-level GPU partitioning (requires supported GPUs like A100)
|
|
# - time-slicing: Software-level GPU sharing (works with most NVIDIA GPUs)
|
|
strategy: "time-slicing"
|
|
# Number of time-slicing replicas (only used when strategy is "time-slicing")
|
|
timeSlicingReplicas: 5
|
|
|
|
# Node selector for GPU workloads (adjust labels based on your cluster configuration)
|
|
nodeSelector:
|
|
accelerator: nvidia
|
|
|
|
# Tolerations for GPU nodes (adjust based on your cluster's GPU node taints)
|
|
tolerations:
|
|
- key: "sku"
|
|
operator: "Equal"
|
|
value: "gpu"
|
|
effect: "NoSchedule"
|
|
|
|
# Resource limits and requests
|
|
resources:
|
|
limits:
|
|
memory: "8Gi"
|
|
nvidia.com/gpu: "1"
|
|
requests:
|
|
memory: "4Gi"
|
|
cpu: "1000m"
|
|
|
|
# Pod security context
|
|
# The upstream ollama/ollama image is built to run as root and writes models to
|
|
# /root/.ollama by default. To meet Pod Security Standards "restricted", we run
|
|
# as a non-root user (1001) and rely on fsGroup to make the mounted PVC writable.
|
|
# Override OLLAMA_MODELS env (or remount /root/.ollama) if your image expects root.
|
|
podSecurityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 1001
|
|
runAsGroup: 1001
|
|
fsGroup: 1001
|
|
|
|
# Container security context
|
|
# readOnlyRootFilesystem is intentionally false — Ollama writes model blobs to its data dir.
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 1001
|
|
runAsGroup: 1001
|
|
|
|
# Environment variables
|
|
env:
|
|
NVIDIA_DRIVER_CAPABILITIES: "all"
|
|
OLLAMA_LOAD_TIMEOUT: "-1"
|
|
OLLAMA_KEEP_ALIVE: "-1"
|
|
OLLAMA_DEBUG: "1"
|
|
# The default OLLAMA model dir is /root/.ollama, which a non-root user can't write.
|
|
# Point it at a path under the writable PVC mount instead.
|
|
HOME: "/tmp"
|
|
OLLAMA_MODELS: "/data/models"
|
|
|
|
# Persistence configuration
|
|
persistence:
|
|
enabled: true
|
|
storageClass: ""
|
|
size: 100Gi
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
|
|
# Service configuration
|
|
service:
|
|
type: ClusterIP
|
|
port: 11434
|
|
targetPort: 11434
|
|
|
|
# Health checks
|
|
startupProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 11434
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 10
|
|
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 11434
|
|
initialDelaySeconds: 60
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 5
|
|
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /
|
|
port: 11434
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
|
|
# Additional volumes for ollama deployment
|
|
extraVolumes: []
|
|
extraVolumeMounts: []
|
|
|
|
# Presidio PII redaction service (analyzer + anonymizer combined, port 5001).
|
|
# When enabled, the app's PII_URL is auto-wired to this in-cluster service so the
|
|
# Guardrails PII block and on-demand masking work. To additionally enable automatic
|
|
# log redaction, set app.env.PII_REDACTION="true" AND app.env.INTERNAL_API_BASE_URL
|
|
# to the in-cluster app service URL (the redaction path calls the app's own
|
|
# /api/guardrails/mask-batch, which must be reachable from inside the cluster).
|
|
pii:
|
|
# Enable/disable the PII redaction service
|
|
enabled: false
|
|
|
|
# Image configuration. repository resolves to ghcr.io/simstudioai/pii — the
|
|
# sim.image helper auto-prepends global.imageRegistry to simstudioai/* repos,
|
|
# so do NOT fully-qualify it here.
|
|
image:
|
|
repository: simstudioai/pii
|
|
tag: "" # defaults to Chart.AppVersion
|
|
digest: "" # sha256: pin overrides tag
|
|
pullPolicy: IfNotPresent
|
|
|
|
# NER engine: "spacy" (default) or "gliner" (opt-in zero-shot transformer NER
|
|
# for PERSON/LOCATION/NRP/DATE_TIME; regex/checksum recognizers are identical
|
|
# on both engines). The image ships both engines, so this is a pure env flip
|
|
# — no image change needed. Note: gliner on CPU is orders of magnitude slower
|
|
# than spacy; it is intended for GPU nodes.
|
|
engine: "spacy"
|
|
|
|
# Torch device for the gliner engine: "cpu", "cuda", or "cuda:N". Empty
|
|
# auto-detects (cuda when a GPU is visible, else cpu). GPU resource requests
|
|
# (nvidia.com/gpu) are not wired yet — GPU scheduling is an infra follow-up.
|
|
device: ""
|
|
|
|
# Number of replicas
|
|
replicaCount: 1
|
|
|
|
# Resource limits and requests. Five large spaCy models (en/es/it/pl/fi, ~2.2GB)
|
|
# load into memory at startup, so size generously.
|
|
resources:
|
|
limits:
|
|
memory: "8Gi"
|
|
cpu: "2000m"
|
|
requests:
|
|
memory: "4Gi"
|
|
cpu: "1000m"
|
|
|
|
# The sim.podSecurityContext / sim.containerSecurityContext helpers already inject
|
|
# non-root + uid/gid/fsGroup 1001 + restricted defaults (drop ALL caps, no privilege
|
|
# escalation, RuntimeDefault seccomp), matching docker/pii.Dockerfile's USER 1001.
|
|
# Leave these empty to inherit those defaults; override only if you must.
|
|
podSecurityContext: {}
|
|
securityContext: {}
|
|
|
|
# Environment variables for the service container
|
|
env: {}
|
|
|
|
# Node scheduling. nodeSelector pins the (memory-heavy, ~4Gi) service to a
|
|
# node pool; tolerations are inherited from the top-level `tolerations` key
|
|
# (shared with app/realtime), and topologySpreadConstraints spreads replicas.
|
|
nodeSelector: {}
|
|
topologySpreadConstraints: []
|
|
|
|
# Service configuration
|
|
service:
|
|
type: ClusterIP
|
|
port: 5001
|
|
targetPort: 5001
|
|
|
|
# Health checks. Cold start is slow (~180s) while spaCy models load, so the
|
|
# startupProbe grace is generous (failureThreshold * periodSeconds ≈ 300s).
|
|
startupProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 5001
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 30
|
|
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 5001
|
|
periodSeconds: 30
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 5001
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
|
|
# Additional volumes for the pii deployment
|
|
extraVolumes: []
|
|
extraVolumeMounts: []
|
|
|
|
# Ingress configuration
|
|
# When services share the same host, paths are consolidated into a single rule.
|
|
# Path order: realtime paths, copilot paths, then app paths (most specific first).
|
|
# Ensure specific paths (e.g., /socket.io, /copilot) come before catch-all paths (/).
|
|
ingress:
|
|
enabled: false
|
|
className: nginx
|
|
|
|
annotations:
|
|
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
|
# Production recommendations (uncomment & adjust to your environment):
|
|
#
|
|
# Automatic TLS via cert-manager. Issuer name varies per cluster
|
|
# (e.g. letsencrypt-prod, letsencrypt-staging, internal-ca).
|
|
# cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
#
|
|
# Allow larger uploads (knowledge base / file ingestion).
|
|
# nginx.ingress.kubernetes.io/proxy-body-size: "50m"
|
|
#
|
|
# Long timeouts for streaming SSE / LLM responses.
|
|
# nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
|
|
# nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
|
|
|
|
# Main application (use / as catch-all)
|
|
app:
|
|
host: sim.local
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
|
|
# Realtime service (use /socket.io when sharing host with app)
|
|
realtime:
|
|
host: sim-ws.local
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
|
|
# Copilot service (optional, use /copilot when sharing host)
|
|
# copilot:
|
|
# host: sim.local
|
|
# paths:
|
|
# - path: /copilot
|
|
# pathType: Prefix
|
|
|
|
tls:
|
|
enabled: false
|
|
secretName: sim-tls-secret
|
|
|
|
# Internal Ingress configuration
|
|
# Same path ordering rules apply as above.
|
|
ingressInternal:
|
|
enabled: false
|
|
className: nginx
|
|
annotations: {}
|
|
|
|
app:
|
|
host: sim-internal.local
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
|
|
realtime:
|
|
host: sim-internal.local
|
|
paths:
|
|
- path: /socket.io
|
|
pathType: Prefix
|
|
|
|
# copilot:
|
|
# host: sim-internal.local
|
|
# paths:
|
|
# - path: /copilot
|
|
# pathType: Prefix
|
|
|
|
tls:
|
|
enabled: false
|
|
secretName: sim-internal-tls-secret
|
|
|
|
# Service Account configuration
|
|
serviceAccount:
|
|
# Specifies whether a service account should be created
|
|
create: true
|
|
|
|
# Annotations to add to the service account
|
|
annotations: {}
|
|
|
|
# The name of the service account to use
|
|
name: ""
|
|
|
|
# Horizontal Pod Autoscaler for app and realtime deployments.
|
|
# When enabled, the chart omits spec.replicas from the Deployment so the HPA
|
|
# owns replica count. Requires metrics-server (or a custom metrics adapter
|
|
# if you use customMetrics) installed in the cluster.
|
|
autoscaling:
|
|
enabled: false
|
|
minReplicas: 1
|
|
maxReplicas: 10
|
|
targetCPUUtilizationPercentage: 80
|
|
targetMemoryUtilizationPercentage: 80
|
|
# Custom metrics for scaling (advanced users can add custom metrics here)
|
|
customMetrics: []
|
|
# Scaling behavior configuration (customize scale-up/down policies)
|
|
# Example configuration:
|
|
# behavior:
|
|
# scaleDown:
|
|
# stabilizationWindowSeconds: 300
|
|
# policies:
|
|
# - type: Percent
|
|
# value: 50
|
|
# periodSeconds: 60
|
|
# scaleUp:
|
|
# stabilizationWindowSeconds: 60
|
|
# policies:
|
|
# - type: Percent
|
|
# value: 100
|
|
# periodSeconds: 15
|
|
# - type: Pods
|
|
# value: 2
|
|
# periodSeconds: 60
|
|
behavior: {}
|
|
|
|
# Pod disruption budget
|
|
# Note: PDBs only protect against voluntary disruptions (node drains, autoscaler).
|
|
# They do NOT affect rolling updates — use deployment.strategy.rollingUpdate for that.
|
|
#
|
|
# Tri-state activation:
|
|
# enabled: true → force PDB on (any replicaCount)
|
|
# enabled: false → force PDB off (explicit opt-out, even at replicaCount > 1)
|
|
# enabled: null → auto-enable when replicaCount > 1 (recommended default)
|
|
podDisruptionBudget:
|
|
enabled: null
|
|
# Use either minAvailable or maxUnavailable (not both).
|
|
# Percentages scale with HPA / replicaCount; absolute numbers do not.
|
|
# Default `maxUnavailable: "25%"` allows rolling updates while keeping
|
|
# 75% of pods serving — matches the K8s docs guidance for stateless HA
|
|
# frontends (https://kubernetes.io/docs/tasks/run-application/configure-pdb/).
|
|
# - minAvailable: minimum pods that must remain available (e.g., 1, "90%")
|
|
# - maxUnavailable: maximum pods that can be unavailable (e.g., 1, "25%")
|
|
minAvailable: null
|
|
maxUnavailable: "25%"
|
|
# unhealthyPodEvictionPolicy: allows eviction of unhealthy pods during node drains
|
|
# Options: IfHealthyBudget (default) | AlwaysAllow (recommended for production)
|
|
# Set to null to use K8s default (IfHealthyBudget)
|
|
unhealthyPodEvictionPolicy: null
|
|
|
|
# Prometheus monitoring integration.
|
|
# Creates a ServiceMonitor CR scraped by the Prometheus Operator. Requires
|
|
# the kube-prometheus-stack (or prometheus-operator) CRDs to be installed
|
|
# in the cluster — otherwise the manifest is rejected by the API server.
|
|
monitoring:
|
|
# ServiceMonitor for Prometheus
|
|
serviceMonitor:
|
|
enabled: false
|
|
# Additional labels for ServiceMonitor
|
|
labels: {}
|
|
# Additional annotations for ServiceMonitor
|
|
annotations: {}
|
|
# Metrics path
|
|
path: /metrics
|
|
# Scrape interval
|
|
interval: 30s
|
|
# Scrape timeout
|
|
scrapeTimeout: 10s
|
|
# Target labels to be added to scraped metrics
|
|
targetLabels: []
|
|
# Metric relabeling configurations
|
|
metricRelabelings: []
|
|
# Relabeling configurations
|
|
relabelings: []
|
|
|
|
# NetworkPolicy for east-west and egress isolation.
|
|
# When enabled, the chart creates policies that allow Sim components to talk
|
|
# to each other and to required external services (DNS, HTTPS) while blocking
|
|
# everything else. The egress block additionally blacklists cloud metadata
|
|
# endpoints (169.254.169.254/32, 169.254.170.2/32) by default — extend
|
|
# egressExceptCidrs with your cluster's API server CIDR for tighter isolation.
|
|
# Your CNI must support NetworkPolicy (Calico, Cilium, GKE Dataplane V2, etc.).
|
|
networkPolicy:
|
|
enabled: false
|
|
|
|
# NetworkPolicyPeers allowed to reach the app/realtime pods on the
|
|
# ingress-controller path. Defaults to `- {}` (any source), which matches the
|
|
# common case where the ingress controller is the only thing routing to these
|
|
# ports. To restrict ingress to a specific controller namespace, replace with:
|
|
# ingressFrom:
|
|
# - namespaceSelector:
|
|
# matchLabels:
|
|
# kubernetes.io/metadata.name: ingress-nginx
|
|
ingressFrom:
|
|
- {}
|
|
|
|
# Custom ingress rules appended to the policy
|
|
ingress: []
|
|
|
|
# Custom egress rules appended to the policy.
|
|
# Kept as a top-level list (not a map) for backward compatibility with the
|
|
# pre-1.0 chart that shipped `networkPolicy.egress: []`. Existing values
|
|
# files continue to work without changes.
|
|
egress: []
|
|
|
|
# CIDRs excluded from broad HTTPS (443) egress.
|
|
# Defaults block AWS/GCP/Azure IMDS (169.254.169.254/32) and ECS task metadata
|
|
# (169.254.170.2/32). Add your cluster's API server CIDR for stronger isolation.
|
|
egressExceptCidrs:
|
|
- "169.254.169.254/32"
|
|
- "169.254.170.2/32"
|
|
|
|
# Shared storage for enterprise workflows requiring data sharing between pods
|
|
sharedStorage:
|
|
enabled: false
|
|
# Storage class for shared volumes (must support ReadWriteMany access)
|
|
storageClass: ""
|
|
# Default access modes for shared volumes (ReadWriteMany required for multi-pod access)
|
|
defaultAccessModes:
|
|
- ReadWriteMany
|
|
# Define shared volumes for your workflows (uncomment and customize as needed)
|
|
# Example volume configurations:
|
|
# volumes:
|
|
# - name: output-share
|
|
# size: 100Gi
|
|
# accessModes:
|
|
# - ReadWriteMany
|
|
# annotations: {}
|
|
# - name: rawdata-share
|
|
# size: 500Gi
|
|
# accessModes:
|
|
# - ReadWriteMany
|
|
# - name: model-share
|
|
# size: 200Gi
|
|
# accessModes:
|
|
# - ReadWriteMany
|
|
# - name: logs-share
|
|
# size: 50Gi
|
|
# accessModes:
|
|
# - ReadWriteMany
|
|
volumes: []
|
|
|
|
# Additional volumes for custom configurations (advanced users)
|
|
extraVolumes: []
|
|
extraVolumeMounts: []
|
|
|
|
# Branding configuration
|
|
# Use this to inject custom branding assets (logos, CSS, etc.) into the application
|
|
branding:
|
|
# Enable/disable branding ConfigMap
|
|
enabled: false
|
|
|
|
# Mount path in the container where branding files will be available
|
|
mountPath: "/app/public/branding"
|
|
|
|
# Text files (CSS, JSON, HTML, etc.) - values are plain text
|
|
# Example:
|
|
# files:
|
|
# custom.css: |
|
|
# .logo { background-color: #ff0000; }
|
|
# config.json: |
|
|
# {"theme": "dark"}
|
|
files: {}
|
|
|
|
# Binary files (PNG, JPG, ICO, etc.) - values must be base64 encoded
|
|
# Generate base64 with: base64 -i logo.png | tr -d '\n'
|
|
# Example:
|
|
# binaryFiles:
|
|
# logo.png: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk..."
|
|
# favicon.ico: "AAABAAEAEBAAAAEAIABoBAAAFgAAAA..."
|
|
binaryFiles: {}
|
|
|
|
# Additional environment variables for custom integrations
|
|
extraEnvVars: []
|
|
|
|
# Pod annotations for custom metadata
|
|
podAnnotations: {}
|
|
|
|
# Pod labels for custom labeling
|
|
podLabels: {}
|
|
|
|
# Affinity settings for advanced pod scheduling
|
|
affinity: {}
|
|
|
|
# Tolerations for scheduling on tainted nodes
|
|
tolerations: []
|
|
|
|
# CronJob configuration for scheduled tasks
|
|
cronjobs:
|
|
# Enable/disable all cron jobs
|
|
enabled: true
|
|
|
|
# Individual job configurations
|
|
jobs:
|
|
scheduleExecution:
|
|
enabled: true
|
|
name: schedule-execution
|
|
schedule: "*/1 * * * *"
|
|
path: "/api/schedules/execute"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
gmailWebhookPoll:
|
|
enabled: true
|
|
name: gmail-webhook-poll
|
|
schedule: "*/1 * * * *"
|
|
path: "/api/webhooks/poll/gmail"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
outlookWebhookPoll:
|
|
enabled: true
|
|
name: outlook-webhook-poll
|
|
schedule: "*/1 * * * *"
|
|
path: "/api/webhooks/poll/outlook"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
rssWebhookPoll:
|
|
enabled: true
|
|
name: rss-webhook-poll
|
|
schedule: "*/1 * * * *"
|
|
path: "/api/webhooks/poll/rss"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
imapWebhookPoll:
|
|
enabled: true
|
|
name: imap-webhook-poll
|
|
schedule: "*/1 * * * *"
|
|
path: "/api/webhooks/poll/imap"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
googleSheetsWebhookPoll:
|
|
enabled: true
|
|
name: google-sheets-webhook-poll
|
|
schedule: "*/1 * * * *"
|
|
path: "/api/webhooks/poll/google-sheets"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
googleDriveWebhookPoll:
|
|
enabled: true
|
|
name: google-drive-webhook-poll
|
|
schedule: "*/1 * * * *"
|
|
path: "/api/webhooks/poll/google-drive"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
googleCalendarWebhookPoll:
|
|
enabled: true
|
|
name: google-calendar-webhook-poll
|
|
schedule: "*/1 * * * *"
|
|
path: "/api/webhooks/poll/google-calendar"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
hubspotWebhookPoll:
|
|
enabled: true
|
|
name: hubspot-webhook-poll
|
|
schedule: "*/1 * * * *"
|
|
path: "/api/webhooks/poll/hubspot"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
renewSubscriptions:
|
|
enabled: true
|
|
name: renew-subscriptions
|
|
schedule: "0 */12 * * *"
|
|
path: "/api/cron/renew-subscriptions"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
reconcileBillingSeats:
|
|
enabled: true
|
|
name: reconcile-billing-seats
|
|
schedule: "0 * * * *"
|
|
path: "/api/cron/reconcile-billing-seats"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
# Releases AgentMail inbox + webhook for workspaces whose Sim Mailer plan
|
|
# lapsed (canceled/downgraded off Max/Enterprise). Tolerates past_due, so a
|
|
# transient payment failure never tears down a paying customer's inbox.
|
|
reconcileInboxEntitlement:
|
|
enabled: true
|
|
name: reconcile-inbox-entitlement
|
|
schedule: "0 3 * * *"
|
|
path: "/api/cron/reconcile-inbox-entitlement"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
workspaceEventsPoll:
|
|
enabled: true
|
|
name: workspace-events-poll
|
|
schedule: "*/15 * * * *"
|
|
path: "/api/workspace-events/poll"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
timePauseResumePoll:
|
|
enabled: true
|
|
name: time-pause-resume-poll
|
|
schedule: "*/1 * * * *"
|
|
path: "/api/resume/poll"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
connectorSync:
|
|
enabled: true
|
|
name: connector-sync
|
|
schedule: "*/5 * * * *"
|
|
path: "/api/knowledge/connectors/sync"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
runDataDrains:
|
|
enabled: true
|
|
name: run-data-drains
|
|
schedule: "0 * * * *"
|
|
path: "/api/cron/run-data-drains"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
# Processes the transactional outbox (deployment side-effects retry / dead-letter)
|
|
# and reaps stale workspace-fork background-work rows. Both are safety nets behind
|
|
# the immediate post-commit processing, so frequent runs keep retries timely.
|
|
outboxProcess:
|
|
enabled: true
|
|
name: outbox-process
|
|
schedule: "*/1 * * * *"
|
|
path: "/api/webhooks/outbox/process"
|
|
concurrencyPolicy: Forbid
|
|
successfulJobsHistoryLimit: 3
|
|
failedJobsHistoryLimit: 1
|
|
|
|
# Global CronJob settings
|
|
image:
|
|
repository: curlimages/curl
|
|
tag: 8.5.0
|
|
pullPolicy: IfNotPresent
|
|
|
|
resources:
|
|
limits:
|
|
memory: "128Mi"
|
|
cpu: "100m"
|
|
requests:
|
|
memory: "64Mi"
|
|
cpu: "50m"
|
|
|
|
restartPolicy: OnFailure
|
|
activeDeadlineSeconds: 300
|
|
startingDeadlineSeconds: 60
|
|
|
|
# Pod security context
|
|
podSecurityContext:
|
|
fsGroup: 1001
|
|
|
|
# Container security context
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 1001
|
|
|
|
# Observability and telemetry configuration
|
|
telemetry:
|
|
# Enable/disable telemetry collection
|
|
enabled: false
|
|
|
|
# OpenTelemetry Collector image
|
|
image:
|
|
repository: otel/opentelemetry-collector-contrib
|
|
tag: 0.91.0
|
|
pullPolicy: IfNotPresent
|
|
|
|
# Number of collector replicas
|
|
replicaCount: 1
|
|
|
|
# Resource limits and requests
|
|
resources:
|
|
limits:
|
|
memory: "512Mi"
|
|
cpu: "500m"
|
|
requests:
|
|
memory: "256Mi"
|
|
cpu: "100m"
|
|
|
|
# Node selector for telemetry pod scheduling (leave empty to allow scheduling on any node)
|
|
nodeSelector: {}
|
|
|
|
# Tolerations for telemetry workloads
|
|
tolerations: []
|
|
|
|
# Affinity for telemetry workloads
|
|
affinity: {}
|
|
|
|
# Service configuration
|
|
service:
|
|
type: ClusterIP
|
|
|
|
# Jaeger tracing backend
|
|
jaeger:
|
|
enabled: false
|
|
endpoint: "http://jaeger-collector:14250"
|
|
tls:
|
|
enabled: false
|
|
|
|
# Prometheus metrics backend
|
|
prometheus:
|
|
enabled: false
|
|
endpoint: "http://prometheus-server/api/v1/write"
|
|
auth: ""
|
|
|
|
# Generic OTLP backend
|
|
otlp:
|
|
enabled: false
|
|
endpoint: "http://otlp-collector:4317"
|
|
tls:
|
|
enabled: false
|
|
|
|
# Pod security context (preserves the collector's original UID/GID/fsGroup)
|
|
podSecurityContext:
|
|
runAsUser: 10001
|
|
runAsGroup: 10001
|
|
fsGroup: 10001
|
|
|
|
# Container security context (sim.containerSecurityContext restricted defaults apply)
|
|
securityContext: {}
|
|
|
|
# Copilot service configuration (optional microservice)
|
|
copilot:
|
|
# Enable/disable the copilot service
|
|
enabled: false
|
|
|
|
# Server deployment configuration
|
|
server:
|
|
# Image configuration
|
|
image:
|
|
repository: simstudioai/copilot
|
|
# tag defaults to Chart.AppVersion. Override with a release tag or pin via image.digest.
|
|
tag: ""
|
|
digest: ""
|
|
pullPolicy: IfNotPresent
|
|
|
|
# Number of replicas
|
|
replicaCount: 1
|
|
|
|
# Resource limits and requests
|
|
resources:
|
|
limits:
|
|
memory: "2Gi"
|
|
cpu: "1000m"
|
|
requests:
|
|
memory: "1Gi"
|
|
cpu: "500m"
|
|
|
|
# Node selector for pod scheduling
|
|
# Leave empty to run on same infrastructure as main Sim platform
|
|
# Or specify labels to isolate on dedicated nodes: { "workload-type": "copilot" }
|
|
nodeSelector: {}
|
|
|
|
# Pod security context
|
|
podSecurityContext:
|
|
fsGroup: 1001
|
|
|
|
# Container security context
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 1001
|
|
|
|
# Environment variables that go through the chart-managed Secret (or ExternalSecret
|
|
# when externalSecrets.enabled=true). Every non-empty key here must have a matching
|
|
# externalSecrets.remoteRefs.copilot entry under ESO — reserve this block for values
|
|
# that are genuinely sensitive or user-provided; static operational config belongs in
|
|
# envDefaults below instead.
|
|
env:
|
|
AGENT_API_DB_ENCRYPTION_KEY: ""
|
|
INTERNAL_API_SECRET: ""
|
|
LICENSE_KEY: ""
|
|
OPENAI_API_KEY_1: ""
|
|
ANTHROPIC_API_KEY_1: ""
|
|
SIM_BASE_URL: ""
|
|
SIM_AGENT_API_KEY: ""
|
|
REDIS_URL: ""
|
|
CORS_ALLOWED_ORIGINS: ""
|
|
OTEL_EXPORTER_OTLP_ENDPOINT: ""
|
|
|
|
# Operational tunables shipped with the chart. Rendered as inline `env:` on the
|
|
# copilot container — NOT written into the chart-managed Secret and NOT required to
|
|
# be mapped when externalSecrets.enabled=true. Override any key by setting
|
|
# copilot.server.envDefaults.KEY in your values file. Move a key into
|
|
# copilot.server.env above only if it must be treated as secret.
|
|
envDefaults:
|
|
PORT: "8080"
|
|
SERVICE_NAME: "copilot"
|
|
ENVIRONMENT: "production"
|
|
LOG_LEVEL: "info"
|
|
|
|
# Optional: additional static environment variables
|
|
extraEnv: []
|
|
|
|
# Optional: references to existing ConfigMaps/Secrets
|
|
extraEnvFrom: []
|
|
|
|
# Optional: additional volumes/mounts (e.g. to back an emptyDir /tmp when
|
|
# enabling securityContext.readOnlyRootFilesystem)
|
|
extraVolumes: []
|
|
extraVolumeMounts: []
|
|
|
|
# Secret generation configuration (set create=false to use an existing secret)
|
|
secret:
|
|
create: true
|
|
name: ""
|
|
annotations: {}
|
|
|
|
# Service configuration
|
|
service:
|
|
type: ClusterIP
|
|
port: 8080
|
|
targetPort: 8080
|
|
|
|
# Health checks
|
|
# Startup probe absorbs cold-start time. Total budget: 30 * 5s = 150s.
|
|
startupProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 8080
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 5
|
|
timeoutSeconds: 3
|
|
failureThreshold: 30
|
|
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 8080
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
timeoutSeconds: 3
|
|
failureThreshold: 3
|
|
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 8080
|
|
initialDelaySeconds: 30
|
|
periodSeconds: 30
|
|
timeoutSeconds: 5
|
|
failureThreshold: 6
|
|
|
|
# Pod Disruption Budget for high availability
|
|
podDisruptionBudget:
|
|
enabled: false
|
|
minAvailable: 1
|
|
|
|
# PostgreSQL database for copilot (separate from main Sim database)
|
|
postgresql:
|
|
# Enable/disable internal PostgreSQL for copilot
|
|
enabled: true
|
|
|
|
# Image configuration
|
|
image:
|
|
repository: postgres
|
|
tag: 17-alpine
|
|
pullPolicy: IfNotPresent
|
|
|
|
# Authentication configuration
|
|
auth:
|
|
username: copilot
|
|
password: "" # REQUIRED - set via --set flag or external secret manager
|
|
database: copilot
|
|
|
|
# Node selector for database pod scheduling
|
|
# Leave empty to run on same infrastructure as main Sim platform
|
|
# Or specify labels to isolate on dedicated nodes: { "workload-type": "copilot" }
|
|
nodeSelector: {}
|
|
|
|
# Resource limits and requests
|
|
resources:
|
|
limits:
|
|
memory: "1Gi"
|
|
cpu: "500m"
|
|
requests:
|
|
memory: "512Mi"
|
|
cpu: "250m"
|
|
|
|
# Pod security context
|
|
# PostgreSQL image's `postgres` user is uid/gid 999.
|
|
podSecurityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 999
|
|
runAsGroup: 999
|
|
fsGroup: 999
|
|
|
|
# Container security context
|
|
# readOnlyRootFilesystem is intentionally false — Postgres writes to /var/lib/postgresql/data.
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 999
|
|
runAsGroup: 999
|
|
|
|
# Persistence configuration
|
|
persistence:
|
|
enabled: true
|
|
storageClass: ""
|
|
size: 10Gi
|
|
accessModes:
|
|
- ReadWriteOnce
|
|
|
|
# Service configuration
|
|
service:
|
|
type: ClusterIP
|
|
port: 5432
|
|
targetPort: 5432
|
|
|
|
# Health checks
|
|
# startupProbe shields liveness from slow first-boot scenarios (pgvector
|
|
# extension init, WAL replay after a crash). Gives postgres up to 150s
|
|
# (30 * 5s) to become ready before liveness takes over.
|
|
startupProbe:
|
|
exec:
|
|
command: ["pg_isready", "-U", "copilot", "-d", "copilot"]
|
|
periodSeconds: 5
|
|
failureThreshold: 30
|
|
timeoutSeconds: 5
|
|
|
|
livenessProbe:
|
|
exec:
|
|
command: ["pg_isready", "-U", "copilot", "-d", "copilot"]
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 5
|
|
timeoutSeconds: 5
|
|
failureThreshold: 10
|
|
|
|
readinessProbe:
|
|
exec:
|
|
command: ["pg_isready", "-U", "copilot", "-d", "copilot"]
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 3
|
|
timeoutSeconds: 5
|
|
failureThreshold: 10
|
|
|
|
# External database configuration (use when connecting to a managed database)
|
|
database:
|
|
existingSecretName: ""
|
|
secretKey: DATABASE_URL
|
|
url: ""
|
|
|
|
# Migration job configuration
|
|
migrations:
|
|
# Enable/disable migrations job
|
|
enabled: true
|
|
|
|
# Image configuration (same as server)
|
|
image:
|
|
repository: simstudioai/copilot
|
|
# tag defaults to Chart.AppVersion. Override with a release tag or pin via image.digest.
|
|
tag: ""
|
|
digest: ""
|
|
pullPolicy: IfNotPresent
|
|
|
|
# Resource limits and requests
|
|
resources:
|
|
limits:
|
|
memory: "512Mi"
|
|
cpu: "500m"
|
|
requests:
|
|
memory: "256Mi"
|
|
cpu: "100m"
|
|
|
|
# Pod security context
|
|
podSecurityContext:
|
|
fsGroup: 1001
|
|
|
|
# Container security context
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 1001
|
|
|
|
# Job configuration
|
|
backoffLimit: 3
|
|
restartPolicy: OnFailure
|
|
|
|
# External Secrets Operator integration
|
|
# Use this to automatically sync secrets from external secret managers (Azure Key Vault, AWS Secrets Manager, etc.)
|
|
# Prerequisites: Install External Secrets Operator in your cluster first
|
|
# See: https://external-secrets.io/latest/introduction/getting-started/
|
|
externalSecrets:
|
|
# Enable External Secrets Operator integration
|
|
enabled: false
|
|
|
|
# ESO API version. Default "v1beta1" — supported by every ESO release from
|
|
# v0.7+ (mid-2023) through current. Set to "v1" only when targeting ESO
|
|
# v0.17+ clusters where the v1 API has graduated.
|
|
apiVersion: "v1beta1"
|
|
|
|
# How often to sync secrets from the external store
|
|
refreshInterval: "1h"
|
|
|
|
# Reference to the SecretStore or ClusterSecretStore
|
|
secretStoreRef:
|
|
# Name of the SecretStore or ClusterSecretStore resource
|
|
name: ""
|
|
# Kind of the store: "SecretStore" (namespaced) or "ClusterSecretStore" (cluster-wide)
|
|
kind: "ClusterSecretStore"
|
|
|
|
# Remote references - paths/keys in your external secret store
|
|
# These map to the secrets that will be created in Kubernetes
|
|
remoteRefs:
|
|
# App secrets (authentication, encryption keys)
|
|
app:
|
|
# Path to BETTER_AUTH_SECRET in external store (e.g., "sim/app/better-auth-secret")
|
|
BETTER_AUTH_SECRET: ""
|
|
# Path to ENCRYPTION_KEY in external store
|
|
ENCRYPTION_KEY: ""
|
|
# Path to INTERNAL_API_SECRET in external store
|
|
INTERNAL_API_SECRET: ""
|
|
# Path to CRON_SECRET in external store (optional)
|
|
CRON_SECRET: ""
|
|
# Path to API_ENCRYPTION_KEY in external store (optional)
|
|
API_ENCRYPTION_KEY: ""
|
|
# Path to REDIS_URL in external store (optional)
|
|
REDIS_URL: ""
|
|
|
|
# PostgreSQL password (for internal PostgreSQL)
|
|
postgresql:
|
|
# Path to PostgreSQL password in external store (e.g., "sim/postgresql/password")
|
|
password: ""
|
|
|
|
# External database password (when using managed database services)
|
|
externalDatabase:
|
|
# Path to external database password in external store
|
|
password: ""
|
|
|
|
# Copilot server secrets (used when copilot.enabled=true and copilot.server.secret.create=true).
|
|
# Every non-empty copilot.server.env key must have a matching entry here, or template
|
|
# rendering fails with a clear "map it or remove it" error — same rule as remoteRefs.app.
|
|
copilot:
|
|
# Path to AGENT_API_DB_ENCRYPTION_KEY in external store
|
|
AGENT_API_DB_ENCRYPTION_KEY: ""
|
|
# Path to INTERNAL_API_SECRET in external store (shared with app/realtime)
|
|
INTERNAL_API_SECRET: ""
|
|
# Path to LICENSE_KEY in external store
|
|
LICENSE_KEY: ""
|
|
# Path to SIM_BASE_URL in external store
|
|
SIM_BASE_URL: ""
|
|
# Path to SIM_AGENT_API_KEY in external store
|
|
SIM_AGENT_API_KEY: ""
|
|
# Path to REDIS_URL in external store
|
|
REDIS_URL: ""
|
|
# Path to OPENAI_API_KEY_1 in external store (one of OPENAI_API_KEY_1/ANTHROPIC_API_KEY_1 required)
|
|
OPENAI_API_KEY_1: ""
|
|
# Path to ANTHROPIC_API_KEY_1 in external store (one of OPENAI_API_KEY_1/ANTHROPIC_API_KEY_1 required)
|
|
ANTHROPIC_API_KEY_1: ""
|
|
|
|
# cert-manager configuration
|
|
# Prerequisites: Install cert-manager in your cluster first
|
|
# See: https://cert-manager.io/docs/installation/
|
|
#
|
|
# This implements the recommended CA bootstrap pattern from cert-manager:
|
|
# 1. Self-signed ClusterIssuer (bootstrap only - creates root CA)
|
|
# 2. Root CA Certificate (self-signed, becomes the trust anchor)
|
|
# 3. CA ClusterIssuer (signs application certificates using root CA)
|
|
#
|
|
# Reference: https://cert-manager.io/docs/configuration/selfsigned/
|
|
certManager:
|
|
# Enable/disable cert-manager issuer resources
|
|
enabled: false
|
|
|
|
# Self-signed ClusterIssuer (used ONLY to bootstrap the root CA)
|
|
# Do not reference this issuer directly for application certificates
|
|
selfSignedIssuer:
|
|
name: "sim-selfsigned-bootstrap-issuer"
|
|
|
|
# Root CA Certificate configuration
|
|
# This certificate is signed by the self-signed issuer and used as the trust anchor
|
|
rootCA:
|
|
# Name of the Certificate resource
|
|
certificateName: "sim-root-ca"
|
|
# Namespace where the root CA certificate and secret will be created
|
|
# Must match cert-manager's cluster-resource-namespace (default: cert-manager)
|
|
namespace: "cert-manager"
|
|
# Common name for the root CA certificate
|
|
commonName: "sim-root-ca"
|
|
# Secret name where the root CA certificate and key will be stored
|
|
secretName: "sim-root-ca-secret"
|
|
# Certificate validity duration (default: 10 years)
|
|
duration: "87600h"
|
|
# Renew before expiry (default: 90 days)
|
|
renewBefore: "2160h"
|
|
# Private key configuration
|
|
privateKey:
|
|
algorithm: RSA
|
|
size: 4096
|
|
# Subject configuration
|
|
subject:
|
|
organizations: []
|
|
# If empty, defaults to the release name
|
|
|
|
# CA ClusterIssuer configuration
|
|
# This is the issuer that applications should reference for obtaining certificates
|
|
caIssuer:
|
|
name: "sim-ca-issuer"
|
|
# Helm test hook (helm test) connectivity probes.
|
|
# Renders a Pod with helm.sh/hook=test that checks the app and realtime
|
|
# Services are reachable from inside the cluster. Run with: helm test <release>
|
|
tests:
|
|
enabled: true
|
|
image:
|
|
repository: busybox
|
|
tag: "1.36"
|
|
pullPolicy: IfNotPresent
|
|
pullSecrets: []
|
|
timeoutSeconds: 5
|
|
resources:
|
|
limits:
|
|
cpu: 100m
|
|
memory: 64Mi
|
|
requests:
|
|
cpu: 10m
|
|
memory: 16Mi
|