Enable auth-service/api-gateway on production, build their images in CI
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
# ArgoCD Applications (tracked copies)
|
||||
|
||||
Personal ArgoCD instance at `argocd.realvuxbaro.me`, on the same k3s cluster
|
||||
that serves `realvuxbaro.me` — not the team's shared ArgoCD
|
||||
(`argocd.vinmec.tech`), which this project does not use or have access to.
|
||||
An earlier version of this directory described a plan to use the team's
|
||||
instance (`docs-legacy/adr/0002-argocd-gitops.md`); that was never started,
|
||||
and the owner deployed this personal instance instead because the team's
|
||||
on-prem infra was heavier than needed for a single-operator project.
|
||||
|
||||
## Why these files exist
|
||||
|
||||
Until 2026-08-18, `medical-chatbot-app` and `medical-chatbot-data` existed
|
||||
only as live objects inside ArgoCD — created once via the API during the
|
||||
2026-08-17 cutover, never captured as a manifest. Losing the ArgoCD instance
|
||||
would have meant losing the Application *definitions* too, even though the
|
||||
Helm values they render (`values-production.yaml`,
|
||||
`values-production-data.yaml`) were already tracked. These two files close
|
||||
that gap: they are the disaster-recovery source for the Application objects
|
||||
themselves.
|
||||
|
||||
## What's tracked vs. what isn't
|
||||
|
||||
`project`, `source` (repo/path/revision/valueFiles), `destination`, and
|
||||
`syncPolicy` are tracked — verified byte-for-byte against the live objects on
|
||||
2026-08-18. `medical-chatbot-app.yaml` deliberately omits the live
|
||||
Application's inline `spec.source.helm.values`: it currently carries the
|
||||
CI-rewritten image tags and, as a known gap, a plaintext Grafana admin
|
||||
password that belongs in a Kubernetes Secret instead (needs cluster write
|
||||
access this repo's automation doesn't have — not yet done). See the comment
|
||||
at the top of that file before ever applying it.
|
||||
|
||||
## Files
|
||||
|
||||
- `applications/medical-chatbot-app.yaml` — ai-service, web, observability.
|
||||
Serves both `realvuxbaro.me` and `readytochat.realvuxbaro.me`.
|
||||
- `applications/medical-chatbot-data.yaml` — PostgreSQL + Qdrant, split into
|
||||
its own Application so an app-side sync or prune can never touch the
|
||||
PersistentVolumeClaims.
|
||||
|
||||
## Known gaps
|
||||
|
||||
- `project: default` on both — no RBAC/project scoping.
|
||||
- Image tags move through `.github/scripts/sync_practice_argocd.py` and
|
||||
`rollback-k3s.yml` mutating the live Application directly via the ArgoCD
|
||||
API, not through a Git commit — a real GitOps setup would use an image
|
||||
updater that writes the tag back to Git. Not yet built.
|
||||
- The Grafana admin password gap above.
|
||||
@@ -0,0 +1,51 @@
|
||||
# Tracked copy of the live `medical-chatbot-app` Application (k3s, personal
|
||||
# ArgoCD instance at argocd.realvuxbaro.me). Verified against the live object
|
||||
# 2026-08-18 — every field below matches `status.sync.status: Synced`,
|
||||
# `status.health.status: Healthy`.
|
||||
#
|
||||
# This Application serves BOTH realvuxbaro.me and readytochat.realvuxbaro.me
|
||||
# (same release, same Pods) since the 2026-08-17 cutover.
|
||||
#
|
||||
# Deliberately NOT reproduced here: `spec.source.helm.values`. The live
|
||||
# Application carries two things inline that must never live in Git:
|
||||
#
|
||||
# - aiService.image.tag / web.image.tag — rewritten on every push by
|
||||
# .github/scripts/sync_practice_argocd.py (or by rollback-k3s.yml for a
|
||||
# rollback). A tag committed here would go stale the moment CI runs again,
|
||||
# and applying this file naively would silently roll the running image
|
||||
# back to whatever tag happened to be in Git.
|
||||
# - secret.grafanaAdminPassword — a real credential. It must never enter
|
||||
# Git history. It belongs in a proper Kubernetes Secret referenced via
|
||||
# `secret.existingSecret` (see infra/helm/medical-chatbot/values.yaml),
|
||||
# not inline on the Application — that migration hasn't been done yet
|
||||
# (it needs cluster write access this repo's automation doesn't have).
|
||||
#
|
||||
# Applying this file (`argocd app create -f` or the ArgoCD UI) recreates the
|
||||
# Application's STRUCTURE — source, destination, sync policy — for disaster
|
||||
# recovery. It does NOT restore the current image tag or the Grafana
|
||||
# password: set the tag afterward via `rollback-k3s.yml` (target_sha = the
|
||||
# last known-good commit) and re-enter the Grafana password by hand.
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: medical-chatbot-app
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://github.com/BaoVu2k4/vsf-duocthu.git
|
||||
targetRevision: master
|
||||
path: infra/helm/medical-chatbot
|
||||
helm:
|
||||
valueFiles:
|
||||
- values.yaml
|
||||
- values-production.yaml
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: medical-chatbot-app
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
@@ -0,0 +1,39 @@
|
||||
# Tracked copy of the live `medical-chatbot-data` Application (k3s, personal
|
||||
# ArgoCD instance at argocd.realvuxbaro.me). Verified against the live object
|
||||
# 2026-08-18 — every field below matches `status.sync.status: Synced`,
|
||||
# `status.health.status: Healthy`.
|
||||
#
|
||||
# Owns PostgreSQL and Qdrant only (the 15,100-point corpus and query
|
||||
# history). Deliberately a separate Application from medical-chatbot-app so
|
||||
# that an app-side sync failure, prune, or rollback can never delete the
|
||||
# PersistentVolumeClaims — see values-production-data.yaml.
|
||||
#
|
||||
# Unlike medical-chatbot-app, the live Application carries no inline
|
||||
# `spec.source.helm.values` at all: this release has no image tag CI rewrites
|
||||
# and no secret, so it is already fully represented by this file plus
|
||||
# values.yaml + values-production-data.yaml. Applying this file for disaster
|
||||
# recovery needs no follow-up step.
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: medical-chatbot-data
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://github.com/BaoVu2k4/vsf-duocthu.git
|
||||
targetRevision: master
|
||||
path: infra/helm/medical-chatbot
|
||||
helm:
|
||||
valueFiles:
|
||||
- values.yaml
|
||||
- values-production-data.yaml
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: medical-chatbot-data
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
@@ -94,32 +94,31 @@ services:
|
||||
# ports: ["8000:8000"]
|
||||
# depends_on: [qdrant]
|
||||
#
|
||||
# api-gateway:
|
||||
# build: ../../apps/api-gateway
|
||||
# env_file: ../../apps/api-gateway/.env
|
||||
# ports: ["3000:3000"]
|
||||
# depends_on: [auth-service, user-service, chat-service]
|
||||
#
|
||||
# auth-service:
|
||||
# build: ../../apps/auth-service
|
||||
# env_file: ../../apps/auth-service/.env
|
||||
# depends_on: [postgres]
|
||||
#
|
||||
# user-service:
|
||||
# build: ../../apps/user-service
|
||||
# env_file: ../../apps/user-service/.env
|
||||
# depends_on: [postgres]
|
||||
#
|
||||
# chat-service:
|
||||
# build: ../../apps/chat-service
|
||||
# env_file: ../../apps/chat-service/.env
|
||||
# depends_on: [postgres, ai-service]
|
||||
#
|
||||
# web:
|
||||
# build: ../../apps/web
|
||||
# ports: ["3001:3000"]
|
||||
# depends_on: [api-gateway]
|
||||
|
||||
# auth-service and api-gateway are real (see the plan this was built
|
||||
# from) — user-service/chat-service stay commented above pending their own
|
||||
# scope, and ai-service/web stay commented per the pre-existing
|
||||
# host-during-dev convention noted at the top of this file.
|
||||
auth-service:
|
||||
build: ../../apps/auth-service
|
||||
env_file: ../../apps/auth-service/.env
|
||||
ports:
|
||||
- "3010:3010"
|
||||
depends_on:
|
||||
- postgres
|
||||
|
||||
api-gateway:
|
||||
build: ../../apps/api-gateway
|
||||
env_file: ../../apps/api-gateway/.env
|
||||
ports:
|
||||
- "3000:3000"
|
||||
depends_on:
|
||||
- auth-service
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
qdrant-data:
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
{{- if .Values.apiGateway.enabled }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "medical-chatbot.fullname" . }}-api-gateway
|
||||
labels:
|
||||
{{- include "medical-chatbot.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: api-gateway
|
||||
spec:
|
||||
replicas: {{ .Values.apiGateway.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: api-gateway
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: api-gateway
|
||||
annotations:
|
||||
checksum/runtime-config: {{ dict "port" .Values.apiGateway.service.port | toJson | sha256sum | quote }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "medical-chatbot.serviceAccountName" . }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml .Values.global.imagePullSecrets | nindent 8 }}
|
||||
containers:
|
||||
- name: api-gateway
|
||||
image: {{ include "medical-chatbot.image" (dict "image" .Values.apiGateway.image "name" "apiGateway") | quote }}
|
||||
imagePullPolicy: {{ .Values.apiGateway.image.pullPolicy }}
|
||||
ports:
|
||||
- { name: http, containerPort: {{ .Values.apiGateway.service.port }} }
|
||||
env:
|
||||
- name: PORT
|
||||
value: {{ .Values.apiGateway.service.port | quote }}
|
||||
- name: AUTH_SERVICE_URL
|
||||
value: {{ printf "http://%s-auth-service:%d" (include "medical-chatbot.fullname" .) (.Values.authService.service.port | int) | quote }}
|
||||
resources:
|
||||
{{- toYaml .Values.apiGateway.resources | nindent 12 }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "medical-chatbot.fullname" . }}-api-gateway
|
||||
labels:
|
||||
{{- include "medical-chatbot.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: api-gateway
|
||||
spec:
|
||||
type: {{ .Values.apiGateway.service.type }}
|
||||
selector:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: api-gateway
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.apiGateway.service.port }}
|
||||
targetPort: http
|
||||
{{- end }}
|
||||
@@ -0,0 +1,122 @@
|
||||
{{- if .Values.authService.enabled }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "medical-chatbot.fullname" . }}-auth-service
|
||||
labels:
|
||||
{{- include "medical-chatbot.labels" . | nindent 4 }}
|
||||
data:
|
||||
JWT_EXPIRES_IN: {{ .Values.authService.config.jwtExpiresIn | quote }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "medical-chatbot.fullname" . }}-auth-service
|
||||
labels:
|
||||
{{- include "medical-chatbot.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: auth-service
|
||||
spec:
|
||||
replicas: {{ .Values.authService.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: auth-service
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: auth-service
|
||||
annotations:
|
||||
checksum/runtime-config: {{ .Values.authService.config | toJson | sha256sum | quote }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "medical-chatbot.serviceAccountName" . }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml .Values.global.imagePullSecrets | nindent 8 }}
|
||||
{{- if or .Values.authService.migration.enabled .Values.authService.seed.enabled }}
|
||||
initContainers:
|
||||
{{- if .Values.authService.migration.enabled }}
|
||||
- name: migrate
|
||||
image: {{ include "medical-chatbot.image" (dict "image" .Values.authService.image "name" "authService") | quote }}
|
||||
imagePullPolicy: {{ .Values.authService.image.pullPolicy }}
|
||||
command: ["node", "dist/migrate.js"]
|
||||
env:
|
||||
- name: POSTGRES_DSN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "medical-chatbot.secretName" . }}
|
||||
key: postgres-dsn
|
||||
- name: JWT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "medical-chatbot.secretName" . }}
|
||||
key: jwt-secret
|
||||
{{- end }}
|
||||
{{- if .Values.authService.seed.enabled }}
|
||||
- name: seed
|
||||
image: {{ include "medical-chatbot.image" (dict "image" .Values.authService.image "name" "authService") | quote }}
|
||||
imagePullPolicy: {{ .Values.authService.image.pullPolicy }}
|
||||
command: ["node", "dist/seed.js"]
|
||||
env:
|
||||
- name: POSTGRES_DSN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "medical-chatbot.secretName" . }}
|
||||
key: postgres-dsn
|
||||
- name: JWT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "medical-chatbot.secretName" . }}
|
||||
key: jwt-secret
|
||||
- name: ADMIN_SEED_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "medical-chatbot.secretName" . }}
|
||||
key: admin-seed-password
|
||||
- name: DEMO_SEED_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "medical-chatbot.secretName" . }}
|
||||
key: demo-seed-password
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: auth-service
|
||||
image: {{ include "medical-chatbot.image" (dict "image" .Values.authService.image "name" "authService") | quote }}
|
||||
imagePullPolicy: {{ .Values.authService.image.pullPolicy }}
|
||||
ports:
|
||||
- { name: http, containerPort: {{ .Values.authService.service.port }} }
|
||||
envFrom:
|
||||
- configMapRef: { name: {{ include "medical-chatbot.fullname" . }}-auth-service }
|
||||
env:
|
||||
- name: PORT
|
||||
value: {{ .Values.authService.service.port | quote }}
|
||||
- name: POSTGRES_DSN
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "medical-chatbot.secretName" . }}
|
||||
key: postgres-dsn
|
||||
- name: JWT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "medical-chatbot.secretName" . }}
|
||||
key: jwt-secret
|
||||
resources:
|
||||
{{- toYaml .Values.authService.resources | nindent 12 }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "medical-chatbot.fullname" . }}-auth-service
|
||||
labels:
|
||||
{{- include "medical-chatbot.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: auth-service
|
||||
spec:
|
||||
type: {{ .Values.authService.service.type }}
|
||||
selector:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: auth-service
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.authService.service.port }}
|
||||
targetPort: http
|
||||
{{- end }}
|
||||
@@ -10,4 +10,20 @@ stringData:
|
||||
postgres-password: {{ .Values.secret.postgresPassword | quote }}
|
||||
postgres-dsn: {{ printf "postgresql://duoc_thu:%s@%s:5432/duoc_thu" .Values.secret.postgresPassword (default (printf "%s-postgres" (include "medical-chatbot.fullname" .)) .Values.secret.postgresHost) | quote }}
|
||||
grafana-admin-password: {{ .Values.secret.grafanaAdminPassword | quote }}
|
||||
{{- if and .Values.aws.staticCredentials.enabled .Values.aws.staticCredentials.accessKeyId }}
|
||||
aws-access-key-id: {{ .Values.aws.staticCredentials.accessKeyId | quote }}
|
||||
aws-secret-access-key: {{ .Values.aws.staticCredentials.secretAccessKey | quote }}
|
||||
{{- end }}
|
||||
{{- if or .Values.authService.enabled .Values.apiGateway.enabled }}
|
||||
{{/* Required (not defaulted) once either service is turned on — same
|
||||
fail-closed posture as the image-tag guard above: a guessable or empty
|
||||
secret here would let anyone forge an admin JWT. */}}
|
||||
jwt-secret: {{ required "secret.jwtSecret is required when authService or apiGateway is enabled" .Values.secret.jwtSecret | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.authService.seed.enabled }}
|
||||
{{/* Required (not defaulted) once the seed job runs — see the comment on
|
||||
secret.adminSeedPassword in values.yaml for why "1" must never reach here. */}}
|
||||
admin-seed-password: {{ required "secret.adminSeedPassword is required when authService.seed.enabled" .Values.secret.adminSeedPassword | quote }}
|
||||
demo-seed-password: {{ required "secret.demoSeedPassword is required when authService.seed.enabled" .Values.secret.demoSeedPassword | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -27,6 +27,20 @@ spec:
|
||||
env:
|
||||
- name: AI_SERVICE_URL
|
||||
value: {{ printf "http://%s-ai-service:%v" (include "medical-chatbot.fullname" .) .Values.aiService.service.port | quote }}
|
||||
{{- if .Values.apiGateway.enabled }}
|
||||
- name: API_GATEWAY_URL
|
||||
value: {{ printf "http://%s-api-gateway:%d" (include "medical-chatbot.fullname" .) (.Values.apiGateway.service.port | int) | quote }}
|
||||
{{- end }}
|
||||
{{- if or .Values.authService.enabled .Values.apiGateway.enabled }}
|
||||
{{/* Only middleware.ts needs this (verifies the admin JWT locally
|
||||
at the edge) — the BFF routes never see it, they just forward the
|
||||
cookie's raw token to the gateway. */}}
|
||||
- name: JWT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "medical-chatbot.secretName" . }}
|
||||
key: jwt-secret
|
||||
{{- end }}
|
||||
ports:
|
||||
- { name: http, containerPort: 3000 }
|
||||
readinessProbe:
|
||||
|
||||
@@ -53,6 +53,19 @@ aiService:
|
||||
answerModelId: qwen.qwen3-next-80b-a3b
|
||||
rerankEnabled: true
|
||||
|
||||
# First real-auth rollout to production (2026-08-18). The seed `admin`/`demo`
|
||||
# passwords are NOT set here — they're secret, so they go inline on the live
|
||||
# Application the same way secret.grafanaAdminPassword already does (see the
|
||||
# comment in infra/argocd/applications/medical-chatbot-app.yaml). The chart
|
||||
# fails closed via `required` if secret.jwtSecret / adminSeedPassword /
|
||||
# demoSeedPassword are missing, so an inline-values update that forgets one
|
||||
# of them breaks sync loudly instead of seeding "1".
|
||||
authService:
|
||||
enabled: true
|
||||
|
||||
apiGateway:
|
||||
enabled: true
|
||||
|
||||
observability:
|
||||
grafana:
|
||||
# Dashboards stay open so a demo needs no credentials, but read-only: this
|
||||
|
||||
@@ -18,6 +18,46 @@ secret:
|
||||
# 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
|
||||
@@ -68,6 +108,48 @@ web:
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user