# values-gcp.yaml # # When to use: Google Kubernetes Engine (GKE). Configures Persistent Disk # storage, Google Cloud Load Balancer with managed certs, Workload Identity # annotations, and Tesla T4/V100 GPU node selectors for Ollama. # # Prerequisites: # - GKE cluster (Kubernetes 1.25+) # - Workload Identity enabled (for IAM-bound ServiceAccount) # - (optional) Managed certificate or cert-manager for TLS # - (optional) GPU node pool with accelerator labels for Ollama # # Install: # helm install sim ./helm/sim \ # --namespace sim --create-namespace \ # --values ./helm/sim/examples/values-gcp.yaml \ # --set app.env.BETTER_AUTH_SECRET="$BETTER_AUTH_SECRET" \ # --set app.env.ENCRYPTION_KEY="$ENCRYPTION_KEY" \ # --set app.env.INTERNAL_API_SECRET="$INTERNAL_API_SECRET" \ # --set app.env.CRON_SECRET="$CRON_SECRET" \ # --set postgresql.auth.password="$POSTGRES_PASSWORD" # # Choosing a secret strategy # -------------------------- # Pick one of three modes — see helm/sim/README.md for details. # # 1. Inline (default below): set values directly in app.env. The chart # writes every key into a chart-managed Secret. Simplest, but stores # plaintext in your values file. # # 2. existingSecret: pre-create a Kubernetes Secret out-of-band and # reference it via app.secrets.existingSecret.name. You are # responsible for ensuring the Secret contains every key your app # needs (BETTER_AUTH_SECRET, ENCRYPTION_KEY, INTERNAL_API_SECRET, # OPENAI_API_KEY, ...). The chart-managed Secret is not rendered in # this mode, so anything missing from your Secret will be empty at # runtime. # # 3. External Secrets Operator (ESO): sync from Google Secret Manager # via the External Secrets Operator. Map every key via # externalSecrets.remoteRefs.app.. The chart fails template # rendering if a key is set in app.env but not mapped — see the # commented ESO block at the bottom of this file. # Global configuration global: imageRegistry: "ghcr.io" storageClass: "standard-rwo" # Main application app: enabled: true replicaCount: 2 # Node selector for application pods # Uncomment and customize based on your GKE node labels: # nodeSelector: # cloud.google.com/gke-nodepool: "default-pool" resources: limits: memory: "4Gi" cpu: "2000m" requests: memory: "2Gi" cpu: "1000m" # Production URLs (REQUIRED - update with your actual domain names) env: NEXT_PUBLIC_APP_URL: "https://simstudio.acme.com" BETTER_AUTH_URL: "https://simstudio.acme.com" # SOCKET_SERVER_URL is auto-detected (uses internal service http://sim-realtime:3002) NEXT_PUBLIC_SOCKET_URL: "https://simstudio-ws.acme.com" # Public WebSocket URL for browsers # Security settings (REQUIRED - replace with your own secure secrets) # Generate using: openssl rand -hex 32 BETTER_AUTH_SECRET: "your-secure-production-auth-secret-here" ENCRYPTION_KEY: "your-secure-production-encryption-key-here" INTERNAL_API_SECRET: "your-secure-production-internal-api-secret-here" CRON_SECRET: "your-secure-production-cron-secret-here" # Optional: API Key Encryption (RECOMMENDED for production) # Generate 64-character hex string using: openssl rand -hex 32 API_ENCRYPTION_KEY: "your-64-char-hex-api-encryption-key-here" # Optional but recommended NODE_ENV: "production" NEXT_TELEMETRY_DISABLED: "1" # GCP-specific environment variables GOOGLE_CLOUD_PROJECT: "your-project-id" GOOGLE_CLOUD_REGION: "us-central1" # Realtime service realtime: enabled: true replicaCount: 2 # Node selector for realtime pods # Uncomment and customize based on your GKE node labels: # nodeSelector: # cloud.google.com/gke-nodepool: "default-pool" resources: limits: memory: "4Gi" cpu: "1000m" requests: memory: "2Gi" cpu: "500m" env: NEXT_PUBLIC_APP_URL: "https://simstudio.acme.com" BETTER_AUTH_URL: "https://simstudio.acme.com" BETTER_AUTH_SECRET: "your-secure-production-auth-secret-here" ALLOWED_ORIGINS: "https://simstudio.acme.com" NODE_ENV: "production" # Database migrations migrations: enabled: true resources: limits: memory: "2Gi" cpu: "1000m" requests: memory: "1Gi" cpu: "500m" # PostgreSQL database postgresql: enabled: true # Node selector for database pods # Uncomment and customize (recommended: memory-optimized machine types): # nodeSelector: # cloud.google.com/gke-nodepool: "database-pool" # Database authentication (REQUIRED - set secure credentials) auth: username: postgres password: "your-secure-postgres-password" database: simstudio # Resource allocation optimized for GKE resources: limits: memory: "4Gi" cpu: "2000m" requests: memory: "2Gi" cpu: "1000m" # Persistent storage using Google Cloud Persistent Disk persistence: enabled: true storageClass: "standard-rwo" size: 50Gi accessModes: - ReadWriteOnce # SSL/TLS configuration (requires cert-manager to be installed) tls: enabled: false # Set to true if cert-manager is installed certificatesSecret: postgres-tls-secret # PostgreSQL performance tuning for GCP infrastructure config: maxConnections: 1000 sharedBuffers: "2GB" maxWalSize: "8GB" minWalSize: "160MB" # Ollama AI models with GPU acceleration (GCP GPU instances) # Set ollama.enabled: false if you don't need local AI models ollama: enabled: false replicaCount: 1 # GPU node targeting - uncomment and customize for GPU node pools # Recommended: T4 or V100 GPU instances # nodeSelector: # cloud.google.com/gke-nodepool: "gpu-pool" # cloud.google.com/gke-accelerator: "nvidia-tesla-t4" tolerations: - key: "nvidia.com/gpu" operator: "Equal" value: "present" effect: "NoSchedule" # GPU resource allocation for AI model serving gpu: enabled: true count: 1 resources: limits: memory: "16Gi" cpu: "4000m" nvidia.com/gpu: "1" requests: memory: "8Gi" cpu: "2000m" # High-performance SSD storage for AI models persistence: enabled: true storageClass: "premium-rwo" size: 100Gi accessModes: - ReadWriteOnce env: NVIDIA_DRIVER_CAPABILITIES: "all" OLLAMA_LOAD_TIMEOUT: "-1" OLLAMA_KEEP_ALIVE: "-1" OLLAMA_DEBUG: "1" # Ingress using Google Cloud Load Balancer ingress: enabled: true className: gce annotations: kubernetes.io/ingress.class: gce kubernetes.io/ingress.global-static-ip-name: "simstudio-ip" networking.gke.io/managed-certificates: "simstudio-ssl-cert" kubernetes.io/ingress.allow-http: "false" # Main application app: host: simstudio.acme.com paths: - path: / pathType: Prefix # Realtime service realtime: host: simstudio-ws.acme.com paths: - path: / pathType: Prefix # TLS configuration tls: enabled: true secretName: simstudio-tls-secret # Pod disruption budget for high availability podDisruptionBudget: enabled: true minAvailable: null maxUnavailable: 1 unhealthyPodEvictionPolicy: AlwaysAllow # Network policies networkPolicy: enabled: true # Pod anti-affinity for high availability across GCP zones affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app.kubernetes.io/name operator: In values: ["simstudio"] topologyKey: kubernetes.io/hostname - weight: 50 podAffinityTerm: labelSelector: matchExpressions: - key: app.kubernetes.io/name operator: In values: ["simstudio"] topologyKey: topology.gke.io/zone # Service Account with Workload Identity integration serviceAccount: create: true annotations: iam.gke.io/gcp-service-account: "simstudio@your-project-id.iam.gserviceaccount.com" # Additional environment variables for GCP service integration extraEnvVars: - name: GOOGLE_APPLICATION_CREDENTIALS value: "/var/secrets/google/key.json" # Additional volumes for service account credentials extraVolumes: - name: google-cloud-key secret: secretName: google-service-account-key extraVolumeMounts: - name: google-cloud-key mountPath: /var/secrets/google readOnly: true # ----------------------------------------------------------------------------- # External Secrets Operator (ESO) — recommended for production on GCP # ----------------------------------------------------------------------------- # To switch from inline secrets to ESO: # 1. Install external-secrets in the cluster (https://external-secrets.io). # 2. Create a ClusterSecretStore backed by Google Secret Manager and bind # Workload Identity from this namespace's ServiceAccount. # 3. Remove entries from app.env above (or leave them and the chart will # fail-fast naming each unmapped key). # 4. Uncomment the block below and replace the paths with the names of the # secrets in your project. # # externalSecrets: # enabled: true # secretStoreRef: # name: "gcp-secret-store" # name of your ClusterSecretStore # kind: "ClusterSecretStore" # remoteRefs: # app: # BETTER_AUTH_SECRET: "sim-better-auth-secret" # ENCRYPTION_KEY: "sim-encryption-key" # INTERNAL_API_SECRET: "sim-internal-api-secret" # CRON_SECRET: "sim-cron-secret" # API_ENCRYPTION_KEY: "sim-api-encryption-key" # # Provider keys typical for a GCP deployment. Vertex AI auth is # # usually handled by Workload Identity, so VERTEX_CREDENTIALS is # # only needed when running outside the GCP credential chain. # OPENAI_API_KEY: "sim-openai-api-key" # # ANTHROPIC_API_KEY: "sim-anthropic-api-key" # # VERTEX_CREDENTIALS: "sim-vertex-credentials-json" # postgresql: # password: "sim-postgresql-password"