feat(helm): mount credentials from Secret and set per-container resources

- chart: add secretEnv (existingSecret + keys) rendered as secretKeyRef in
  both containers; add resourcesProsody/resourcesSidecar defaults with
  dedicated requests and limits via a containerResources helper
- argo: move prosodyDBpass/fcmApiKey/fileShareSecret/avatarUploadPass out of
  env into secretEnv referencing a prosody-secrets Secret; set dedicated
  resource requests+limits per container
- argo: add prosody-secrets.example.yaml ArgoCD Application (with a warning
  to use Sealed Secrets / External Secrets / SOPS instead of plaintext)
- chart fixes: bump stale appVersion 0.11.6 -> 13.0.6; fix malformed service
  block in values.yaml

Part-of: <http://gitlab.vnc.biz/uxf/vnctalk-prosody/-/merge_requests/3>
This commit is contained in:
2026-07-15 17:58:02 +02:00
parent 3918ec59e9
commit e19cc05403
6 changed files with 162 additions and 11 deletions
+65
View File
@@ -0,0 +1,65 @@
# =============================================================================
# WARNING — UNSAFE EXAMPLE — DO NOT USE AS-IS IN PRODUCTION
# =============================================================================
#
# This file deploys the `prosody-secrets` Secret (consumed by the prosody
# Helm chart's `secretEnv`) through ArgoCD using PLAINTEXT stringData.
#
# Storing raw credentials in Git is unsafe. Committing real secrets here would
# leak them to anyone with repo access and into the full git history. This
# example exists only to show the wiring.
#
# Provide the Secret in a secure manner instead, e.g.:
#
# * Sealed Secrets — commit a SealedSecret (Bitnami); the controller
# decrypts it in-cluster. Replace the Secret below with a
# SealedSecret produced by `kubeseal`.
# * External Secrets Operator — reference an external vault (GCP Secret
# Manager, AWS Secrets Manager, HashiCorp Vault) via a
# SecretStore + ExternalSecret; no secret material in Git.
# * SOPS / age-encrypted manifests decrypted by ArgoCD's KSOPS plugin.
#
# The keys below MUST match `secretEnv.keys` in argo/prosody.yaml:
# prosodyDBpass, fcmApiKey, fileShareSecret, avatarUploadPass
# =============================================================================
apiVersion: v1
kind: Secret
metadata:
name: prosody-secrets
namespace: prosody
labels:
app.kubernetes.io/name: prosody
app.kubernetes.io/managed-by: argocd.argoproj.io
type: Opaque
stringData:
prosodyDBpass: "REPLACE_WITH_REAL_DB_PASSWORD"
fcmApiKey: "REPLACE_WITH_REAL_FCM_API_KEY"
fileShareSecret: "REPLACE_WITH_REAL_FILESHARE_SECRET"
avatarUploadPass: "REPLACE_WITH_REAL_AVATAR_UPLOAD_PASSWORD"
---
# ArgoCD Application that syncs the Secret above into the prosody namespace.
# Point `path` at the directory in your GitOps repo that holds the (sealed /
# encrypted) Secret manifest. This example assumes the Secret lives next to a
# copy of this file in `charts/prosody-secrets`.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: prosody-secrets
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
destination:
server: https://kubernetes.default.svc
namespace: prosody
project: default
source:
path: charts/prosody-secrets
repoURL: git@gitlab.example.com:helmcharts.git
targetRevision: HEAD
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=false
+29 -5
View File
@@ -101,31 +101,55 @@ spec:
autoscaling:
minReplicas: 1
maxReplicas: 1
resources:
# Dedicated resource requests and limits per container. The prosody
# (XMPP) container carries the real workload; the sidecar only serves
# a small static redirect/status page, so it gets a tiny slice.
resourcesProsody:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
resourcesSidecar:
requests:
cpu: 50m
memory: 32Mi
limits:
cpu: 100m
memory: 64Mi
env:
PROSODY_DEBUG: false
prosodyDBhost: 10.20.20.115
prosodyDBname: prosody
prosodyDBuser: prosody
prosodyDBpass: CHANGEME_DB_PASS
prosodyDBport: 5432
prosodyDomain: example.com
hybridaAuthUrl: "http://api.hybridauth.svc.cluster.local:80/"
fcmApiKey: "CHANGEME_FCM_API_KEY"
fcm_api_url: "http://vnctalk-notificationproxy.vnctalk.svc.cluster.local:3898/notify"
del_api_url: "http://vnctalk-notificationproxy.vnctalk.svc.cluster.local:3898/delete"
fileShareBaseUrl: "https://vnc-fileshare.example.com/share.php/"
fileShareSecret: "CHANGEME_FILESHARE_SECRET"
avatarUploadUrl: "https://avatar.vnc.biz/avatarupload/"
avatarUploadUser: avatar
avatarUploadPass: CHANGEME_AVATAR_UPLOAD_PASS
log_slow_events_threshold: 2.0
secretTestName: prosody-tls
# Sensitive credentials mounted from a pre-provisioned Secret
# (prosody-secrets). Provision out-of-band, e.g.:
# kubectl create secret generic prosody-secrets -n prosody \
# --from-literal=prosodyDBpass=... \
# --from-literal=fcmApiKey=... \
# --from-literal=fileShareSecret=... \
# --from-literal=avatarUploadPass=...
secretEnv:
existingSecret: prosody-secrets
keys:
prosodyDBpass: prosodyDBpass
fcmApiKey: fcmApiKey
fileShareSecret: fileShareSecret
avatarUploadPass: avatarUploadPass
syncPolicy:
automated:
prune: true
+1 -1
View File
@@ -20,4 +20,4 @@ version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 0.11.6
appVersion: 13.0.6
+17
View File
@@ -60,3 +60,20 @@ Create the name of the service account to use
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Resolve the resource block for a named container.
Returns the YAML for a container's `resources:` field (requests/limits) from
`resourcesProsody` / `resourcesSidecar`, both of which have chart defaults
that can be overridden by the caller.
Usage:
{{- include "prosody.containerResources" (dict "ctx" . "container" "prosody") | nindent 12 }}
*/}}
{{- define "prosody.containerResources" -}}
{{- $ctx := .ctx -}}
{{- $container := .container -}}
{{- $perContainer := dict "prosody" $ctx.Values.resourcesProsody "sidecar" $ctx.Values.resourcesSidecar -}}
{{- toYaml (get $perContainer $container) -}}
{{- end -}}
+16 -2
View File
@@ -79,12 +79,19 @@ spec:
tcpSocket:
port: 5582
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- include "prosody.containerResources" (dict "ctx" . "container" "prosody") | nindent 12 }}
env:
{{- range $key, $value := $.Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- range $envName, $secretKey := $.Values.secretEnv.keys }}
- name: {{ $envName }}
valueFrom:
secretKeyRef:
name: {{ $.Values.secretEnv.existingSecret | quote }}
key: {{ $secretKey | quote }}
{{- end }}
- name: sidecar
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
@@ -110,12 +117,19 @@ spec:
path: /
port: 8080
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- include "prosody.containerResources" (dict "ctx" . "container" "sidecar") | nindent 12 }}
env:
{{- range $key, $value := $.Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- range $envName, $secretKey := $.Values.secretEnv.keys }}
- name: {{ $envName }}
valueFrom:
secretKeyRef:
name: {{ $.Values.secretEnv.existingSecret | quote }}
key: {{ $secretKey | quote }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
+34 -3
View File
@@ -42,8 +42,7 @@ tlsUpdates:
service:
type: NodePort
port:
number: 5280
port: 5280
annotations: {}
node:
@@ -77,10 +76,42 @@ ingress:
ingress_additional_host:
enabled: false
resources:
# Non-sensitive environment variables rendered as literal env values.
# Sensitive credentials must NOT go here — use secretEnv below.
env: {}
# Credentials mounted from a pre-provisioned Secret via secretKeyRef.
# Create the Secret out-of-band (e.g. kubectl create secret generic
# prosody-secrets --from-literal=prosodyDBpass=... ) and reference it here.
secretEnv:
# Name of an existing Secret in the release namespace.
existingSecret: ""
# Map of environment variable name -> key within the Secret.
keys: {}
# prosodyDBpass: prosodyDBpass
# fcmApiKey: fcmApiKey
# fileShareSecret: fileShareSecret
# avatarUploadPass: avatarUploadPass
# Dedicated resource requests and limits for each container in the pod.
# `resourcesProsody` is the XMPP server (the real workload); `resourcesSidecar`
# is the static-file/redirect http-server (a tiny slice). Each accepts the
# standard Kubernetes resources shape with `requests` and `limits`.
resourcesProsody:
requests:
cpu: 2000m
memory: 2048Mi
limits:
cpu: 4000m
memory: 4096Mi
resourcesSidecar:
requests:
cpu: 100m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
autoscaling:
enabled: false