mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-07-04 10:52:17 +02:00
Replace bundled Bitnami subcharts with in-chart manifests on official images
The Bitnami catalog removed all versioned image tags from docker.io/bitnami in Aug 2025 (old images frozen in bitnamilegacy, maintained catalog now behind a Broadcom subscription), so the bundled postgresql/redis/minio subcharts no longer pull. Replace them with plain in-chart manifests built on official upstream images, keeping the internal/all-in-one path fully self-contained and free of third-party chart packaging that can disappear: - internal-postgres.yaml: pgvector/pgvector:pg17 — upstream Postgres plus the `vector` extension the migrations require. POSTGRES_USER=dograh is the initdb superuser, so CREATE EXTENSION vector succeeds. - internal-redis.yaml: redis:7.4-alpine, password-protected, AOF persistence. - internal-minio.yaml: minio/minio, root creds shared with the app via a single secret (can't drift); the app auto-creates its bucket. Service/secret names are unchanged (<rel>-postgresql, <rel>-redisinternal-master, <rel>-minio) so the app wiring is untouched. Dep passwords are generated once and persisted across upgrades via lookup. Drop the Chart.yaml dependencies, Chart.lock, and the `helm dependency` step; the internal manifests gate on the mode toggles (database.mode=internal, etc.). Also fixes surfaced by smoke-testing on a live EKS cluster: - Dockerfile: ship the per-service run_*.sh entrypoints the chart invokes. - migrate-job: run as a post-install/pre-upgrade hook (the bundled Postgres does not exist during pre-install) with a wait-for-postgres init container. - backend env: declare POSTGRES_PASSWORD/REDIS_PASSWORD before the DATABASE_URL/ REDIS_URL that interpolate them (Kubernetes only expands back-references). - worker liveness probes: pgrep isn't in the slim runtime image; check /proc/1/cmdline instead (each worker execs its process as PID 1). - UI: set HOSTNAME=0.0.0.0 so Next.js standalone doesn't bind to the k8s-injected pod name (which maps to the pod IP only, breaking port-forward/loopback). Verified end-to-end on EKS 1.36: all pods Ready, migrations applied (pgvector extension + 27 tables), UI login page and web API served via port-forward. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
89d1e5ee89
commit
00e290671f
20 changed files with 614 additions and 190 deletions
|
|
@ -141,7 +141,22 @@ ENV PYTHONUNBUFFERED=1
|
|||
# Copy application code (chown at copy-time avoids a duplicate /app layer
|
||||
# from a later `RUN chown -R`, which would double the on-disk size of /app).
|
||||
COPY --chown=dograh:dograh ./api ./api
|
||||
COPY --chown=dograh:dograh ./scripts/start_services_docker.sh ./scripts/start_services_docker.sh
|
||||
|
||||
# Entrypoint scripts.
|
||||
# start_services_docker.sh — single-container (docker-compose) entrypoint
|
||||
# that runs every service in one process tree.
|
||||
# run_*.sh — per-service entrypoints used by the Helm chart,
|
||||
# which runs each workload (web, arq-worker, ari-manager,
|
||||
# campaign-orchestrator, migrate) as its own pod. Keep this list in sync
|
||||
# with the command:[] entries in deploy/helm/dograh/templates/*.yaml.
|
||||
COPY --chown=dograh:dograh \
|
||||
./scripts/start_services_docker.sh \
|
||||
./scripts/run_migrate.sh \
|
||||
./scripts/run_web.sh \
|
||||
./scripts/run_arq_worker.sh \
|
||||
./scripts/run_ari_manager.sh \
|
||||
./scripts/run_campaign_orchestrator.sh \
|
||||
./scripts/
|
||||
|
||||
# ts_validator Node deps (built in ts-deps stage with full node:22-slim image).
|
||||
# The validator runs as a short-lived subprocess from api/mcp_server/ts_bridge.py.
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
dependencies:
|
||||
- name: postgresql
|
||||
repository: oci://registry-1.docker.io/bitnamicharts
|
||||
version: 16.7.27
|
||||
- name: redis
|
||||
repository: oci://registry-1.docker.io/bitnamicharts
|
||||
version: 20.13.4
|
||||
- name: minio
|
||||
repository: oci://registry-1.docker.io/bitnamicharts
|
||||
version: 16.0.10
|
||||
digest: sha256:8a2d769b21e882239fc847a9638758131f388dbd12feabd387671e9a336a2615
|
||||
generated: "2026-05-25T19:49:15.193741+05:30"
|
||||
|
|
@ -27,21 +27,11 @@ sources:
|
|||
maintainers:
|
||||
- name: Dograh
|
||||
|
||||
# Bundled stateful dependencies. Each is gated by its mode toggle in
|
||||
# values.yaml so external-managed deployments do not pull these charts.
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
version: "16.x.x"
|
||||
repository: oci://registry-1.docker.io/bitnamicharts
|
||||
condition: postgresql.enabled
|
||||
# Aliased to redisInternal so the dograh-level `redis.mode` toggle does not
|
||||
# collide with the subchart's values namespace.
|
||||
- name: redis
|
||||
alias: redisInternal
|
||||
version: "20.x.x"
|
||||
repository: oci://registry-1.docker.io/bitnamicharts
|
||||
condition: redisInternal.enabled
|
||||
- name: minio
|
||||
version: "16.x.x"
|
||||
repository: oci://registry-1.docker.io/bitnamicharts
|
||||
condition: minio.enabled
|
||||
# The bundled stateful deps (PostgreSQL, Redis, MinIO) for the internal/all-in-one
|
||||
# modes are plain in-chart manifests (templates/internal-*.yaml) built on official
|
||||
# upstream images — NOT subcharts. This avoids depending on third-party chart
|
||||
# packaging/registries that can change or disappear (as the Bitnami catalog did in
|
||||
# Aug 2025). Production deployments should use the external/managed modes
|
||||
# (database.mode=external, redis.mode=external, storage.mode=s3|externalMinio).
|
||||
#
|
||||
# dependencies: []
|
||||
|
|
|
|||
|
|
@ -15,10 +15,9 @@ exercised against a live cluster.
|
|||
```bash
|
||||
cd deploy/helm/dograh
|
||||
|
||||
# Pull in Bitnami subcharts (network required)
|
||||
helm dependency update
|
||||
|
||||
# Install with defaults (all internal deps, Gateway API exposure)
|
||||
# Install with defaults (all internal deps, Gateway API exposure).
|
||||
# The bundled Postgres/Redis/MinIO are in-chart manifests on official upstream
|
||||
# images — no `helm dependency` / subchart pull step needed.
|
||||
helm install dograh . \
|
||||
--set secrets.ossJwtSecret="$(openssl rand -hex 32)" \
|
||||
--set secrets.turnSecret="$(openssl rand -hex 32)" \
|
||||
|
|
|
|||
|
|
@ -62,10 +62,5 @@ autoscaling:
|
|||
minReplicas: 3
|
||||
maxReplicas: 12
|
||||
|
||||
# Disable bundled deps.
|
||||
postgresql:
|
||||
enabled: false
|
||||
redisInternal:
|
||||
enabled: false
|
||||
minio:
|
||||
enabled: false
|
||||
# No bundled deps: the in-chart Postgres/Redis/MinIO manifests are gated on the
|
||||
# internal modes, so the external/S3 modes above already keep them from rendering.
|
||||
|
|
|
|||
|
|
@ -62,10 +62,7 @@ autoscaling:
|
|||
maxReplicas: 12
|
||||
targetCPUUtilizationPercentage: 70
|
||||
|
||||
# Disable bundled deps when using external services.
|
||||
postgresql:
|
||||
enabled: false
|
||||
redisInternal:
|
||||
enabled: false
|
||||
minio:
|
||||
enabled: false
|
||||
# No bundled deps here: the in-chart Postgres/Redis/MinIO manifests are gated on
|
||||
# the internal modes (database.mode=internal, redis.mode=internal,
|
||||
# storage.mode=internalMinio), so the external/S3 modes set above already keep
|
||||
# them from rendering.
|
||||
|
|
|
|||
|
|
@ -49,13 +49,11 @@ autoscaling:
|
|||
enabled: false
|
||||
|
||||
postgresql:
|
||||
primary:
|
||||
persistence:
|
||||
size: 2Gi
|
||||
redisInternal:
|
||||
master:
|
||||
persistence:
|
||||
size: 1Gi
|
||||
persistence:
|
||||
size: 2Gi
|
||||
redisinternal:
|
||||
persistence:
|
||||
size: 1Gi
|
||||
minio:
|
||||
persistence:
|
||||
size: 5Gi
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ coturn is disabled. Set coturn.enabled=true to deploy media relay.
|
|||
|
||||
=== Migrations ===
|
||||
{{- if .Values.migrate.enabled }}
|
||||
Alembic migrations run as a pre-install / pre-upgrade hook. Inspect with:
|
||||
Alembic migrations run as a post-install / pre-upgrade hook. Inspect with:
|
||||
|
||||
kubectl logs job/{{ include "dograh.migrate.fullname" . }} -n {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
|
|
|
|||
|
|
@ -98,12 +98,60 @@ In-cluster service references for internal deps.
|
|||
{{- define "dograh.redisHost" -}}{{ .Release.Name }}-redisinternal-master{{- end }}
|
||||
{{- define "dograh.minioHost" -}}{{ .Release.Name }}-minio{{- end }}
|
||||
|
||||
{{/*
|
||||
Resolved passwords for the bundled internal deps.
|
||||
Precedence: explicit value in values.yaml wins; else reuse the value already
|
||||
stored in the Secret (so `helm upgrade` does NOT rotate the password and desync a
|
||||
running datastore); else generate a fresh one. `lookup` returns empty during
|
||||
`helm template` (no cluster), so dry renders get a throwaway random value — fine.
|
||||
Each is materialized in exactly one place (the dep's Secret); every other
|
||||
reference is a secretKeyRef, so the generated value is stable within a render.
|
||||
*/}}
|
||||
{{- define "dograh.postgresPassword" -}}
|
||||
{{- if .Values.postgresql.auth.password -}}
|
||||
{{- .Values.postgresql.auth.password -}}
|
||||
{{- else -}}
|
||||
{{- $s := lookup "v1" "Secret" .Release.Namespace (printf "%s-postgresql" .Release.Name) -}}
|
||||
{{- if and $s $s.data (index $s.data "password") -}}
|
||||
{{- index $s.data "password" | b64dec -}}
|
||||
{{- else -}}
|
||||
{{- randAlphaNum 24 -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dograh.redisPassword" -}}
|
||||
{{- if .Values.redisinternal.auth.password -}}
|
||||
{{- .Values.redisinternal.auth.password -}}
|
||||
{{- else -}}
|
||||
{{- $s := lookup "v1" "Secret" .Release.Namespace (printf "%s-redisinternal" .Release.Name) -}}
|
||||
{{- if and $s $s.data (index $s.data "redis-password") -}}
|
||||
{{- index $s.data "redis-password" | b64dec -}}
|
||||
{{- else -}}
|
||||
{{- randAlphaNum 24 -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dograh.minioRootPassword" -}}
|
||||
{{- if .Values.minio.auth.rootPassword -}}
|
||||
{{- .Values.minio.auth.rootPassword -}}
|
||||
{{- else -}}
|
||||
{{- $s := lookup "v1" "Secret" .Release.Namespace (printf "%s-minio" .Release.Name) -}}
|
||||
{{- if and $s $s.data (index $s.data "root-password") -}}
|
||||
{{- index $s.data "root-password" | b64dec -}}
|
||||
{{- else -}}
|
||||
{{- randAlphaNum 24 -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Default DATABASE_URL when database.mode=internal.
|
||||
Bitnami Postgres exposes the password as <release>-postgresql secret key
|
||||
`postgres-password` or `password`. The chart pulls it via envFrom on the
|
||||
generated secret; for clarity we still need the URL string. Auth username
|
||||
defaults to `dograh` (see values.postgresql.auth.username).
|
||||
The bundled Postgres (templates/internal-postgres.yaml) stores the app-user
|
||||
password in the <release>-postgresql Secret under key `password`; dograh.dbEnv
|
||||
projects it into $(POSTGRES_PASSWORD), which this URL interpolates at runtime.
|
||||
Auth username/database default to `dograh` (see values.postgresql.auth).
|
||||
*/}}
|
||||
{{- define "dograh.databaseUrl" -}}
|
||||
{{- if eq .Values.database.mode "internal" -}}
|
||||
|
|
@ -121,6 +169,53 @@ $(REDIS_URL)
|
|||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Database / Redis connection env for backend workloads (web, arq, singletons,
|
||||
migrate).
|
||||
|
||||
ORDER IS LOAD-BEARING. POSTGRES_PASSWORD / REDIS_PASSWORD are declared BEFORE
|
||||
DATABASE_URL / REDIS_URL because Kubernetes only expands a $(VAR) reference to
|
||||
an env var defined *earlier* in the same container's env list — a forward
|
||||
reference is left as the literal string "$(VAR)". DATABASE_URL / REDIS_URL
|
||||
embed $(POSTGRES_PASSWORD) / $(REDIS_PASSWORD) (see dograh.databaseUrl /
|
||||
dograh.redisUrl), so the password vars must come first or the composed URLs
|
||||
ship with a literal "$(POSTGRES_PASSWORD)" as the password.
|
||||
*/}}
|
||||
{{- define "dograh.dbEnv" -}}
|
||||
{{- if eq .Values.database.mode "internal" }}
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-postgresql
|
||||
key: password
|
||||
{{- end }}
|
||||
{{- if eq .Values.redis.mode "internal" }}
|
||||
- name: REDIS_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-redisinternal
|
||||
key: redis-password
|
||||
{{- end }}
|
||||
- name: DATABASE_URL
|
||||
value: {{ include "dograh.databaseUrl" . | quote }}
|
||||
- name: REDIS_URL
|
||||
value: {{ include "dograh.redisUrl" . | quote }}
|
||||
{{- if eq .Values.storage.mode "internalMinio" }}
|
||||
{{- /* Internal MinIO creds come from the <release>-minio secret, the same
|
||||
source the MinIO server uses (no ordering constraint — no composition). */}}
|
||||
- name: MINIO_ACCESS_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-minio
|
||||
key: root-user
|
||||
- name: MINIO_SECRET_KEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-minio
|
||||
key: root-password
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common env block for backend workloads (web, arq, singletons, migrate).
|
||||
References the ConfigMap + Secret via envFrom. DATABASE_URL and REDIS_URL
|
||||
|
|
@ -131,16 +226,6 @@ are added inline because they may need composition from subchart secrets.
|
|||
name: {{ include "dograh.configMapName" . }}
|
||||
- secretRef:
|
||||
name: {{ include "dograh.secretName" . }}
|
||||
{{- if eq .Values.database.mode "internal" }}
|
||||
- secretRef:
|
||||
name: {{ .Release.Name }}-postgresql
|
||||
optional: true
|
||||
{{- end }}
|
||||
{{- if eq .Values.redis.mode "internal" }}
|
||||
- secretRef:
|
||||
name: {{ .Release.Name }}-redisinternal
|
||||
optional: true
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
|
|
|
|||
|
|
@ -43,24 +43,7 @@ spec:
|
|||
envFrom:
|
||||
{{- include "dograh.backendEnvFrom" . | nindent 12 }}
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
value: {{ include "dograh.databaseUrl" . | quote }}
|
||||
- name: REDIS_URL
|
||||
value: {{ include "dograh.redisUrl" . | quote }}
|
||||
{{- if eq .Values.database.mode "internal" }}
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-postgresql
|
||||
key: password
|
||||
{{- end }}
|
||||
{{- if eq .Values.redis.mode "internal" }}
|
||||
- name: REDIS_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-redisinternal
|
||||
key: redis-password
|
||||
{{- end }}
|
||||
{{- include "dograh.dbEnv" . | nindent 12 }}
|
||||
# exec probe — no HTTP endpoint exists on ari-manager.
|
||||
livenessProbe:
|
||||
{{- toYaml .Values.ariManager.livenessProbe | nindent 12 }}
|
||||
|
|
|
|||
|
|
@ -40,24 +40,7 @@ spec:
|
|||
envFrom:
|
||||
{{- include "dograh.backendEnvFrom" . | nindent 12 }}
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
value: {{ include "dograh.databaseUrl" . | quote }}
|
||||
- name: REDIS_URL
|
||||
value: {{ include "dograh.redisUrl" . | quote }}
|
||||
{{- if eq .Values.database.mode "internal" }}
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-postgresql
|
||||
key: password
|
||||
{{- end }}
|
||||
{{- if eq .Values.redis.mode "internal" }}
|
||||
- name: REDIS_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-redisinternal
|
||||
key: redis-password
|
||||
{{- end }}
|
||||
{{- include "dograh.dbEnv" . | nindent 12 }}
|
||||
livenessProbe:
|
||||
{{- toYaml .Values.workers.livenessProbe | nindent 12 }}
|
||||
resources:
|
||||
|
|
|
|||
|
|
@ -43,24 +43,7 @@ spec:
|
|||
envFrom:
|
||||
{{- include "dograh.backendEnvFrom" . | nindent 12 }}
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
value: {{ include "dograh.databaseUrl" . | quote }}
|
||||
- name: REDIS_URL
|
||||
value: {{ include "dograh.redisUrl" . | quote }}
|
||||
{{- if eq .Values.database.mode "internal" }}
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-postgresql
|
||||
key: password
|
||||
{{- end }}
|
||||
{{- if eq .Values.redis.mode "internal" }}
|
||||
- name: REDIS_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-redisinternal
|
||||
key: redis-password
|
||||
{{- end }}
|
||||
{{- include "dograh.dbEnv" . | nindent 12 }}
|
||||
# exec probe — no HTTP endpoint exists on campaign-orchestrator.
|
||||
livenessProbe:
|
||||
{{- toYaml .Values.campaignOrchestrator.livenessProbe | nindent 12 }}
|
||||
|
|
|
|||
137
deploy/helm/dograh/templates/internal-minio.yaml
Normal file
137
deploy/helm/dograh/templates/internal-minio.yaml
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
{{- if eq .Values.storage.mode "internalMinio" }}
|
||||
{{- /*
|
||||
Bundled MinIO for storage.mode=internalMinio, official upstream image. Single
|
||||
replica (Recreate strategy — the RWO volume can't be shared). The app creates
|
||||
its bucket on first use (bucket_exists → make_bucket), so no provisioning Job.
|
||||
|
||||
The root credentials live in <release>-minio and are consumed BOTH by the MinIO
|
||||
server (MINIO_ROOT_USER / MINIO_ROOT_PASSWORD) and by the app (MINIO_ACCESS_KEY /
|
||||
MINIO_SECRET_KEY, wired in dograh.dbEnv) — one source of truth, so they can't
|
||||
drift. For production use storage.mode=s3 or externalMinio.
|
||||
*/}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-minio
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dograh.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: minio
|
||||
type: Opaque
|
||||
stringData:
|
||||
root-user: {{ .Values.minio.auth.rootUser | default "minioadmin" | quote }}
|
||||
root-password: {{ include "dograh.minioRootPassword" . | quote }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-minio
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dograh.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: minio
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: api
|
||||
port: 9000
|
||||
targetPort: api
|
||||
- name: console
|
||||
port: 9001
|
||||
targetPort: console
|
||||
selector:
|
||||
{{- include "dograh.selectorLabels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: minio
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-minio
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dograh.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: minio
|
||||
spec:
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
{{- if .Values.minio.persistence.storageClass }}
|
||||
storageClassName: {{ .Values.minio.persistence.storageClass | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.minio.persistence.size | quote }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-minio
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dograh.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: minio
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "dograh.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: minio
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "dograh.selectorLabels" . | nindent 8 }}
|
||||
app.kubernetes.io/component: minio
|
||||
spec:
|
||||
securityContext:
|
||||
fsGroup: 1000
|
||||
containers:
|
||||
- name: minio
|
||||
image: {{ printf "%s/%s:%s" (.Values.minio.image.registry | default "docker.io") .Values.minio.image.repository (.Values.minio.image.tag | toString) | quote }}
|
||||
imagePullPolicy: {{ .Values.minio.image.pullPolicy | default "IfNotPresent" }}
|
||||
args:
|
||||
- server
|
||||
- /data
|
||||
- --console-address
|
||||
- ":9001"
|
||||
env:
|
||||
- name: MINIO_ROOT_USER
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-minio
|
||||
key: root-user
|
||||
- name: MINIO_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-minio
|
||||
key: root-password
|
||||
ports:
|
||||
- name: api
|
||||
containerPort: 9000
|
||||
- name: console
|
||||
containerPort: 9001
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /minio/health/ready
|
||||
port: api
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /minio/health/live
|
||||
port: api
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
resources:
|
||||
{{- toYaml .Values.minio.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Release.Name }}-minio
|
||||
{{- end }}
|
||||
118
deploy/helm/dograh/templates/internal-postgres.yaml
Normal file
118
deploy/helm/dograh/templates/internal-postgres.yaml
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
{{- if eq .Values.database.mode "internal" }}
|
||||
{{- /*
|
||||
Bundled PostgreSQL for database.mode=internal.
|
||||
|
||||
Image is the official pgvector build — upstream postgres plus the `vector`
|
||||
extension the app's migrations require (CREATE EXTENSION vector). POSTGRES_USER
|
||||
is the initdb superuser, so the migration can create the (untrusted) extension.
|
||||
|
||||
This is the convenience/all-in-one path. For production, set database.mode=external
|
||||
and point secrets.databaseUrl at a managed Postgres.
|
||||
*/}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-postgresql
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dograh.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: postgresql
|
||||
type: Opaque
|
||||
stringData:
|
||||
password: {{ include "dograh.postgresPassword" . | quote }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-postgresql
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dograh.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: postgresql
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: postgresql
|
||||
port: 5432
|
||||
targetPort: postgresql
|
||||
selector:
|
||||
{{- include "dograh.selectorLabels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: postgresql
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-postgresql
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dograh.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: postgresql
|
||||
spec:
|
||||
serviceName: {{ .Release.Name }}-postgresql
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "dograh.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: postgresql
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "dograh.selectorLabels" . | nindent 8 }}
|
||||
app.kubernetes.io/component: postgresql
|
||||
spec:
|
||||
securityContext:
|
||||
# Official image starts as root, chowns PGDATA, then drops to the
|
||||
# `postgres` uid (999). fsGroup makes the mounted volume group-writable.
|
||||
fsGroup: 999
|
||||
containers:
|
||||
- name: postgresql
|
||||
image: {{ printf "%s/%s:%s" (.Values.postgresql.image.registry | default "docker.io") .Values.postgresql.image.repository (.Values.postgresql.image.tag | toString) | quote }}
|
||||
imagePullPolicy: {{ .Values.postgresql.image.pullPolicy | default "IfNotPresent" }}
|
||||
ports:
|
||||
- name: postgresql
|
||||
containerPort: 5432
|
||||
env:
|
||||
- name: POSTGRES_USER
|
||||
value: {{ .Values.postgresql.auth.username | quote }}
|
||||
- name: POSTGRES_DB
|
||||
value: {{ .Values.postgresql.auth.database | quote }}
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-postgresql
|
||||
key: password
|
||||
# Init into a subdirectory so a mounted volume's lost+found does not
|
||||
# collide with initdb's empty-dir check.
|
||||
- name: PGDATA
|
||||
value: /var/lib/postgresql/data/pgdata
|
||||
readinessProbe:
|
||||
exec:
|
||||
command: ["pg_isready", "-U", {{ .Values.postgresql.auth.username | quote }}, "-d", {{ .Values.postgresql.auth.database | quote }}]
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: ["pg_isready", "-U", {{ .Values.postgresql.auth.username | quote }}, "-d", {{ .Values.postgresql.auth.database | quote }}]
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
resources:
|
||||
{{- toYaml .Values.postgresql.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: data
|
||||
spec:
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
{{- if .Values.postgresql.persistence.storageClass }}
|
||||
storageClassName: {{ .Values.postgresql.persistence.storageClass | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.postgresql.persistence.size | quote }}
|
||||
{{- end }}
|
||||
115
deploy/helm/dograh/templates/internal-redis.yaml
Normal file
115
deploy/helm/dograh/templates/internal-redis.yaml
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
{{- if eq .Values.redis.mode "internal" }}
|
||||
{{- /*
|
||||
Bundled Redis for redis.mode=internal, official upstream image. Single-node,
|
||||
password-protected, AOF persistence. For production set redis.mode=external and
|
||||
point secrets.redisUrl at a managed Redis/Valkey.
|
||||
|
||||
Service name is <release>-redisinternal-master (kept from the previous packaging)
|
||||
so dograh.redisHost / dograh.redisUrl need no change.
|
||||
*/}}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-redisinternal
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dograh.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: redis
|
||||
type: Opaque
|
||||
stringData:
|
||||
redis-password: {{ include "dograh.redisPassword" . | quote }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-redisinternal-master
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dograh.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: redis
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: redis
|
||||
port: 6379
|
||||
targetPort: redis
|
||||
selector:
|
||||
{{- include "dograh.selectorLabels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: redis
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-redisinternal-master
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dograh.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: redis
|
||||
spec:
|
||||
serviceName: {{ .Release.Name }}-redisinternal-master
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "dograh.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: redis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "dograh.selectorLabels" . | nindent 8 }}
|
||||
app.kubernetes.io/component: redis
|
||||
spec:
|
||||
securityContext:
|
||||
runAsUser: 999
|
||||
runAsGroup: 999
|
||||
fsGroup: 999
|
||||
containers:
|
||||
- name: redis
|
||||
image: {{ printf "%s/%s:%s" (.Values.redisinternal.image.registry | default "docker.io") .Values.redisinternal.image.repository (.Values.redisinternal.image.tag | toString) | quote }}
|
||||
imagePullPolicy: {{ .Values.redisinternal.image.pullPolicy | default "IfNotPresent" }}
|
||||
command: ["redis-server"]
|
||||
# $(REDIS_PASSWORD) is expanded by Kubernetes from the env var below.
|
||||
args:
|
||||
- "--requirepass"
|
||||
- "$(REDIS_PASSWORD)"
|
||||
- "--appendonly"
|
||||
- "yes"
|
||||
env:
|
||||
- name: REDIS_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-redisinternal
|
||||
key: redis-password
|
||||
ports:
|
||||
- name: redis
|
||||
containerPort: 6379
|
||||
readinessProbe:
|
||||
exec:
|
||||
command: ["sh", "-c", 'redis-cli -a "$REDIS_PASSWORD" ping | grep -q PONG']
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: ["sh", "-c", 'redis-cli -a "$REDIS_PASSWORD" ping | grep -q PONG']
|
||||
initialDelaySeconds: 20
|
||||
periodSeconds: 15
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
resources:
|
||||
{{- toYaml .Values.redisinternal.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: data
|
||||
spec:
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
{{- if .Values.redisinternal.persistence.storageClass }}
|
||||
storageClassName: {{ .Values.redisinternal.persistence.storageClass | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.redisinternal.persistence.size | quote }}
|
||||
{{- end }}
|
||||
|
|
@ -8,7 +8,14 @@ metadata:
|
|||
{{- include "dograh.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: migrate
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade
|
||||
# post-install (not pre-install): when the bundled Postgres subchart is in
|
||||
# use it is a normal resource, so on a fresh install it does not exist until
|
||||
# after pre-install hooks finish — a pre-install migration would deadlock
|
||||
# waiting for a database Helm has not created yet. post-install runs after
|
||||
# all resources (incl. Postgres) are applied. pre-upgrade is kept so
|
||||
# migrations land before new app code rolls out on upgrades (where the DB
|
||||
# already exists).
|
||||
"helm.sh/hook": post-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "-5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
spec:
|
||||
|
|
@ -27,6 +34,26 @@ spec:
|
|||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if eq .Values.database.mode "internal" }}
|
||||
# post-install fires right after resources are applied — the bundled
|
||||
# Postgres pod may still be starting. Block until its Service routes to a
|
||||
# ready endpoint (endpoints only publish once the pod passes readiness)
|
||||
# before alembic attempts to connect. Reuses the app image (already
|
||||
# pulled for the migrate container) so no extra image is needed.
|
||||
initContainers:
|
||||
- name: wait-for-postgres
|
||||
image: {{ include "dograh.image" . }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
command:
|
||||
- bash
|
||||
- -c
|
||||
- |
|
||||
until (exec 3<>/dev/tcp/{{ include "dograh.postgresHost" . }}/5432) 2>/dev/null; do
|
||||
echo "waiting for postgres at {{ include "dograh.postgresHost" . }}:5432 ..."
|
||||
sleep 2
|
||||
done
|
||||
echo "postgres is reachable"
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: migrate
|
||||
image: {{ include "dograh.image" . }}
|
||||
|
|
@ -35,15 +62,7 @@ spec:
|
|||
envFrom:
|
||||
{{- include "dograh.backendEnvFrom" . | nindent 12 }}
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
value: {{ include "dograh.databaseUrl" . | quote }}
|
||||
{{- if eq .Values.database.mode "internal" }}
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-postgresql
|
||||
key: password
|
||||
{{- end }}
|
||||
{{- include "dograh.dbEnv" . | nindent 12 }}
|
||||
resources:
|
||||
{{- toYaml .Values.migrate.resources | nindent 12 }}
|
||||
{{- end }}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ stringData:
|
|||
{{- if eq .Values.redis.mode "external" }}
|
||||
REDIS_URL: {{ required "secrets.redisUrl is required when redis.mode=external" .Values.secrets.redisUrl | quote }}
|
||||
{{- end }}
|
||||
{{- if or (eq .Values.storage.mode "internalMinio") (eq .Values.storage.mode "externalMinio") }}
|
||||
{{- /* internalMinio creds are sourced from the <release>-minio secret via
|
||||
dograh.dbEnv; only externalMinio pulls creds from here. */}}
|
||||
{{- if eq .Values.storage.mode "externalMinio" }}
|
||||
MINIO_ACCESS_KEY: {{ .Values.secrets.minioAccessKey | quote }}
|
||||
MINIO_SECRET_KEY: {{ .Values.secrets.minioSecretKey | quote }}
|
||||
{{- end }}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,13 @@ spec:
|
|||
containerPort: {{ .Values.ui.port }}
|
||||
protocol: TCP
|
||||
env:
|
||||
# Next.js standalone binds to $HOSTNAME (falls back to 0.0.0.0).
|
||||
# Kubernetes injects HOSTNAME=<pod-name>, which /etc/hosts maps to the
|
||||
# pod IP — so without this, Next listens on the pod IP ONLY. In-cluster
|
||||
# Service traffic still works, but loopback (kubectl port-forward, local
|
||||
# health checks) is refused. Pin to 0.0.0.0 to listen on all interfaces.
|
||||
- name: HOSTNAME
|
||||
value: "0.0.0.0"
|
||||
- name: NODE_ENV
|
||||
value: "oss"
|
||||
- name: BACKEND_URL
|
||||
|
|
|
|||
|
|
@ -52,24 +52,7 @@ spec:
|
|||
env:
|
||||
- name: WEB_PORT
|
||||
value: {{ .Values.web.port | quote }}
|
||||
- name: DATABASE_URL
|
||||
value: {{ include "dograh.databaseUrl" . | quote }}
|
||||
- name: REDIS_URL
|
||||
value: {{ include "dograh.redisUrl" . | quote }}
|
||||
{{- if eq .Values.database.mode "internal" }}
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-postgresql
|
||||
key: password
|
||||
{{- end }}
|
||||
{{- if eq .Values.redis.mode "internal" }}
|
||||
- name: REDIS_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Release.Name }}-redisinternal
|
||||
key: redis-password
|
||||
{{- end }}
|
||||
{{- include "dograh.dbEnv" . | nindent 12 }}
|
||||
# Distinct probes: readiness flips fast (drain), liveness is
|
||||
# slower (process aliveness).
|
||||
livenessProbe:
|
||||
|
|
|
|||
|
|
@ -32,13 +32,13 @@ serviceAccount:
|
|||
# Stateful dependency modes.
|
||||
#
|
||||
# database.mode:
|
||||
# internal — bundled Bitnami PostgreSQL subchart (postgresql.enabled=true)
|
||||
# internal — bundled Postgres manifest (pgvector image; see `postgresql` below)
|
||||
# external — operator supplies DATABASE_URL via secrets.databaseUrl
|
||||
# redis.mode:
|
||||
# internal — bundled Bitnami Redis subchart (redis.enabled=true)
|
||||
# internal — bundled Redis manifest (see `redisinternal` below)
|
||||
# external — operator supplies REDIS_URL via secrets.redisUrl
|
||||
# storage.mode:
|
||||
# internalMinio — bundled MinIO subchart (minio.enabled=true)
|
||||
# internalMinio — bundled MinIO manifest (see `minio` below)
|
||||
# externalMinio — operator supplies a MinIO-compatible endpoint + creds
|
||||
# s3 — sets ENABLE_AWS_S3=true; uses AWS S3
|
||||
# exposure.mode:
|
||||
|
|
@ -253,7 +253,10 @@ workers:
|
|||
# exec probe — workers have no HTTP endpoint.
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: ["sh", "-c", "pgrep -f 'arq api.tasks.arq.WorkerSettings' > /dev/null"]
|
||||
# The entrypoint exec's the worker, so it runs as PID 1; grep its cmdline.
|
||||
# Avoids pgrep/procps, which isn't in the slim runtime image. Matching a
|
||||
# single argv token (no spaces) — argv is NUL-separated in /proc.
|
||||
command: ["sh", "-c", "grep -qa api.tasks.arq.WorkerSettings /proc/1/cmdline"]
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 5
|
||||
|
|
@ -285,7 +288,8 @@ ariManager:
|
|||
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: ["sh", "-c", "pgrep -f api.services.telephony.ari_manager > /dev/null"]
|
||||
# PID 1 cmdline check (procps-free; see workers.livenessProbe).
|
||||
command: ["sh", "-c", "grep -qa api.services.telephony.ari_manager /proc/1/cmdline"]
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 5
|
||||
|
|
@ -316,7 +320,8 @@ campaignOrchestrator:
|
|||
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: ["sh", "-c", "pgrep -f api.services.campaign.campaign_orchestrator > /dev/null"]
|
||||
# PID 1 cmdline check (procps-free; see workers.livenessProbe).
|
||||
command: ["sh", "-c", "grep -qa api.services.campaign.campaign_orchestrator /proc/1/cmdline"]
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 5
|
||||
|
|
@ -452,7 +457,8 @@ coturn:
|
|||
# Migration Job
|
||||
# -----------------------------------------------------------------------------
|
||||
migrate:
|
||||
# Run alembic upgrade head as a pre-install / pre-upgrade Helm hook.
|
||||
# Run alembic upgrade head as a Helm hook: post-install (so the bundled
|
||||
# Postgres exists first) and pre-upgrade (so migrations land before new code).
|
||||
enabled: true
|
||||
|
||||
# Hard cap on how long a migration may run. A failed/exceeded migration
|
||||
|
|
@ -484,44 +490,65 @@ autoscaling:
|
|||
targetMemoryUtilizationPercentage: 80
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Bitnami subcharts. Each is gated by its own `enabled` flag set by mode
|
||||
# resolution in templates/_helpers.tpl. Override the subchart's own values
|
||||
# under these keys.
|
||||
# Bundled stateful deps for the internal/all-in-one modes. These are plain
|
||||
# in-chart manifests (templates/internal-*.yaml) on official upstream images —
|
||||
# not subcharts. Each renders only in its internal mode:
|
||||
# postgresql -> database.mode == internal
|
||||
# redisinternal-> redis.mode == internal
|
||||
# minio -> storage.mode == internalMinio
|
||||
# For production, use the external/managed modes instead (see database/redis/
|
||||
# storage above).
|
||||
# -----------------------------------------------------------------------------
|
||||
postgresql:
|
||||
# enabled is set automatically based on database.mode in _helpers.tpl;
|
||||
# this key is read by the subchart's `condition`.
|
||||
enabled: true
|
||||
# Official pgvector image = upstream Postgres + the `vector` extension the app
|
||||
# migrations require. Keep the tag on a supported Postgres major.
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: pgvector/pgvector
|
||||
tag: pg17
|
||||
pullPolicy: IfNotPresent
|
||||
auth:
|
||||
username: dograh
|
||||
password: "" # auto-generated if empty
|
||||
username: dograh # also the initdb superuser (needed for CREATE EXTENSION)
|
||||
password: "" # auto-generated and persisted across upgrades if empty
|
||||
database: dograh
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 8Gi
|
||||
persistence:
|
||||
size: 8Gi
|
||||
storageClass: "" # "" = cluster default StorageClass
|
||||
resources:
|
||||
requests: { cpu: 100m, memory: 256Mi }
|
||||
limits: { cpu: "1", memory: 1Gi }
|
||||
|
||||
redisInternal:
|
||||
# Bitnami Redis subchart values, aliased to redisInternal to avoid
|
||||
# colliding with `redis.mode` above. `redisInternal.enabled` is the gating
|
||||
# flag for whether the subchart deploys.
|
||||
enabled: true
|
||||
redisinternal:
|
||||
# Official upstream Redis. Single node, password-protected, AOF persistence.
|
||||
# (Key kept as `redisinternal` so it doesn't collide with `redis.mode` above.)
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: redis
|
||||
tag: 7.4-alpine
|
||||
pullPolicy: IfNotPresent
|
||||
auth:
|
||||
enabled: true
|
||||
password: "" # auto-generated if empty
|
||||
master:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 8Gi
|
||||
replica:
|
||||
replicaCount: 0 # standalone primary by default
|
||||
password: "" # auto-generated and persisted across upgrades if empty
|
||||
persistence:
|
||||
size: 8Gi
|
||||
storageClass: ""
|
||||
resources:
|
||||
requests: { cpu: 50m, memory: 64Mi }
|
||||
limits: { cpu: 500m, memory: 256Mi }
|
||||
|
||||
minio:
|
||||
enabled: true
|
||||
# Official upstream MinIO. Root creds are shared with the app (single source of
|
||||
# truth) so they can't drift; the app creates its bucket on first use.
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: minio/minio
|
||||
tag: RELEASE.2025-04-22T22-12-26Z
|
||||
pullPolicy: IfNotPresent
|
||||
auth:
|
||||
rootUser: minioadmin
|
||||
rootPassword: "" # auto-generated if empty
|
||||
defaultBuckets: "voice-audio"
|
||||
rootPassword: "" # auto-generated and persisted across upgrades if empty
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 20Gi
|
||||
storageClass: ""
|
||||
resources:
|
||||
requests: { cpu: 100m, memory: 256Mi }
|
||||
limits: { cpu: "1", memory: 1Gi }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue