nameOverride: "" fullnameOverride: "" global: environment: local imagePullSecrets: [] serviceAccount: create: true name: "" annotations: {} secret: create: true existingSecret: "" postgresPassword: duoc_thu # Set when postgres runs in a different Application/release (the # data/app split pattern) — overrides the default in-release host. postgresHost: "" grafanaAdminPassword: change-me # Required (chart render fails without it) once authService or apiGateway # is enabled — signs/verifies every JWT. Must be the same value both # services see, which sharing one Secret key already guarantees. jwtSecret: "" # Required (chart render fails without it) once authService.seed.enabled is # true — the seed job's ON CONFLICT DO NOTHING means whatever password goes # in on the first run is what `admin`/`demo` keep, permanently. Forcing this # to be set explicitly (no "1" default) stops a real deployment from ever # seeding the guessable dev password. Local/Compose dev is unaffected: that # path calls seed.js directly with no env vars set, which still falls back # to "1" in apps/auth-service/src/config.ts. adminSeedPassword: "" demoSeedPassword: "" # AWS credentials for Bedrock (query embedding, rerank, generation). # # Leave `staticCredentials.enabled: false` on AWS-hosted nodes. Both the # Compose host and the k3s node run on EC2, where boto3 resolves credentials # from the instance role over IMDS and no key material exists on disk or in # any manifest — that is the posture every deployment has used so far, and it # is the safer one. `adapters/bedrock_converse.py` builds its client without # passing credentials, so boto3's own chain applies: environment variables # first, then shared config, then the instance role. # # Turn this on only for a cluster with no instance role and no IRSA — an # on-prem cluster, for example — where that chain would find nothing and every # Bedrock call would fail to authenticate. Because environment variables win # over the instance role, leaving this off keeps current behaviour exactly. aws: # Overrides config.py's `aws_region` default (us-east-1); empty leaves the # application default in place. The adapter passes this region to boto3 # explicitly, and pydantic-settings reads this same variable name. region: "" staticCredentials: enabled: false # Used when `secret.create` is true. When pointing at an existing Secret # (`secret.existingSecret`), leave these empty and add the same two keys — # `aws-access-key-id` and `aws-secret-access-key` — to that Secret instead. accessKeyId: "" secretAccessKey: "" aiService: enabled: true replicaCount: 1 image: repository: duocthu-ai-service tag: local pullPolicy: IfNotPresent service: type: ClusterIP port: 8000 config: embeddingProvider: disabled embeddingDimensions: 1024 evidenceMinimumScore: 0.12 awsRegion: us-east-1 answerProvider: disabled answerModelId: deepseek.v3.2 rerankEnabled: false # The Dockerfile bakes the catalog file in at this path; config.py's own # repo-relative default only resolves inside a full monorepo checkout, # not this flattened image layout. Matches apps/ai-service/.env.example. entitiesPath: ./ingestion_data/drug_entities.json qdrantCollection: duocthu_v1 metricsEnabled: true otelEnabled: true otelSampleRatio: 1.0 maxWallClockMs: 40000 maxLlmCallsPerTurn: 8 migration: enabled: true resources: requests: { cpu: 100m, memory: 256Mi } limits: { cpu: "1", memory: 1Gi } web: enabled: true replicaCount: 1 image: repository: duocthu-web tag: local pullPolicy: IfNotPresent service: type: ClusterIP port: 3000 nodePort: null resources: requests: { cpu: 50m, memory: 128Mi } limits: { cpu: 500m, memory: 512Mi } # Both default OFF: this first slice's code exists and can be deployed, but # turning it on for real production traffic is a separate, later, explicit # decision — see the plan this was built from. A fresh `helm install` with # every other default is unaffected either way. authService: enabled: false replicaCount: 1 image: repository: duocthu-auth-service tag: local pullPolicy: IfNotPresent service: type: ClusterIP port: 3010 config: jwtExpiresIn: 12h migration: enabled: true # Idempotent (ON CONFLICT DO NOTHING) — safe to leave on every deploy. # Disable once real registration replaces the two seed accounts, or if the # `admin`/`demo` passwords have been rotated and must not be reset back to # `"1"` by a future rollout. seed: enabled: true resources: requests: { cpu: 50m, memory: 128Mi } limits: { cpu: 250m, memory: 256Mi } apiGateway: enabled: false replicaCount: 1 image: repository: duocthu-api-gateway tag: local pullPolicy: IfNotPresent service: type: ClusterIP port: 3000 resources: requests: { cpu: 50m, memory: 128Mi } limits: { cpu: 250m, memory: 256Mi } ingress: enabled: false className: nginx annotations: {} host: duocthu.local # Additional hostnames served by the same rules as `host`. Used during a # cutover, when one release must answer to both the old and the new name. # A host here is routed but gets no certificate unless it also appears in # `tls` below — see the note in templates/ingress.yaml. extraHosts: [] tls: [] postgres: enabled: true image: postgres:16-alpine storage: 5Gi resources: requests: { cpu: 50m, memory: 128Mi } limits: { cpu: 500m, memory: 512Mi } qdrant: enabled: true # Set when using an external/managed Qdrant; empty uses the bundled Service. url: "" image: qdrant/qdrant:v1.19.0 storage: 10Gi resources: requests: { cpu: 100m, memory: 256Mi } limits: { cpu: "1", memory: 1Gi } observability: enabled: true prometheus: image: prom/prometheus:v3.3.0 retention: 7d storage: 5Gi resources: requests: { cpu: 100m, memory: 256Mi } limits: { cpu: 500m, memory: 1Gi } tempo: image: grafana/tempo:2.7.2 retention: 24h storage: 5Gi resources: requests: { cpu: 100m, memory: 256Mi } limits: { cpu: 500m, memory: 1Gi } collector: image: otel/opentelemetry-collector-contrib:0.123.0 resources: requests: { cpu: 50m, memory: 128Mi } limits: { cpu: 500m, memory: 512Mi } grafana: image: grafana/grafana:11.5.2 service: type: ClusterIP port: 3000 nodePort: null storage: 2Gi # Anonymous access, when enabled, must stay read-only. `role: Admin` on an # internet-reachable Grafana exposes the datasource and dashboard APIs to # anyone; the login form is always available for real admin access. anonymous: enabled: false role: Viewer resources: requests: { cpu: 50m, memory: 128Mi } limits: { cpu: 500m, memory: 512Mi } serviceMonitor: enabled: false interval: 15s additionalLabels: {}