apiVersion: apps/v1 kind: Deployment metadata: name: {{ .Release.Name }}-{{ .Chart.Name }}-deployment labels: app: {{ .Release.Name }}-{{ .Chart.Name }} spec: replicas: {{ include "patchmon.replicas" (dict "scaleDown" .Values.scaleDown "replicas" .Values.patchmon.server.replicas) }} selector: matchLabels: app: {{ .Release.Name }}-{{ .Chart.Name }} template: metadata: name: {{ .Release.Name }}-{{ .Chart.Name }} labels: app: {{ .Release.Name }}-{{ .Chart.Name }} spec: automountServiceAccountToken: false # Pin a stable pod hostname: the server identifies itself in the agent # presence registry (Redis) by hostname, and a Deployment pod's default # hostname changes on every rollout, which would leave stale presence # records behind (upstream pins "patchmon-server" in its compose file # for the same reason). hostname: {{ .Release.Name }}-{{ .Chart.Name }}-server securityContext: {{- include "patchmon.server.podSecurityContext" .Values.patchmon.server.securityContext | nindent 8 }} containers: - name: {{ .Release.Name }}-{{ .Chart.Name }}-server image: "ghcr.io/patchmon/patchmon-server:{{ .Chart.AppVersion }}" imagePullPolicy: IfNotPresent securityContext: {{- include "patchmon.server.containerSecurityContext" .Values.patchmon.server.securityContext | nindent 12 }} ports: - containerPort: 3000 protocol: TCP name: http env: - name: DATABASE_URL valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-postgres-secret key: database-url - name: REDIS_HOST valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-redis-secret key: host - name: REDIS_PORT valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-redis-secret key: port - name: REDIS_USER valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-redis-secret key: username - name: REDIS_PASSWORD valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-redis-secret key: password - name: REDIS_DB valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-redis-secret key: db - name: JWT_SECRET valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-patchmon-secret key: jwt-secret - name: AI_ENCRYPTION_KEY valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-patchmon-secret key: encryption-key - name: SESSION_SECRET valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-patchmon-secret key: session-secret - name: OIDC_ENABLED value: "true" - name: OIDC_ISSUER_URL valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-oidc-secret key: issuer-url - name: OIDC_CLIENT_ID valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-oidc-secret key: client-id - name: OIDC_CLIENT_SECRET valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-oidc-secret key: client-secret - name: OIDC_REDIRECT_URI valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-oidc-secret key: redirect-uri - name: OIDC_SCOPES valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-oidc-secret key: requested-scopes - name: OIDC_AUTO_CREATE_USERS value: "true" # 2.x role vocabulary: superadmin, admin, host_manager, readonly, # user. "viewer" (the 1.x default of this chart) no longer exists; # readonly is its least-privilege equivalent. - name: OIDC_DEFAULT_ROLE value: "readonly" - name: OIDC_DISABLE_LOCAL_AUTH value: "true" - name: OIDC_BUTTON_TEXT valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-oidc-secret key: button-text - name: OIDC_SYNC_ROLES value: "true" - name: OIDC_USER_GROUP valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-oidc-secret key: user-group-name - name: OIDC_ADMIN_GROUP valueFrom: secretKeyRef: name: {{ .Release.Name }}-{{ .Chart.Name }}-oidc-secret key: admin-group-name - name: CORS_ORIGIN value: "https://{{ required "A Domain/Host must be provided" .Values.ingress.domain }}" # Renamed upstream in 2.x (was TRUST_PROXIES= in 1.x): the # server sits behind the ingress-nginx reverse proxy. - name: TRUST_PROXY value: "true" {{- if .Values.patchmon.guacd.enabled }} - name: GUACD_ADDRESS value: "127.0.0.1:4822" {{- end }} {{- range $value := .Values.patchmon.server.env }} {{- if $value.value }} - name: {{ $value.name | quote }} value: {{ tpl $value.value $ | quote }} {{- else if $value.valueFrom }} {{- if $value.valueFrom.secretKeyRef }} - name: {{ $value.name }} valueFrom: secretKeyRef: name: {{ tpl $value.valueFrom.secretKeyRef.name $ | quote }} key: {{ tpl $value.valueFrom.secretKeyRef.key $ | quote }} {{- else if $value.valueFrom.configMapKeyRef }} - name: {{ $value.name }} valueFrom: configMapKeyRef: name: {{ tpl $value.valueFrom.configMapKeyRef.name $ | quote }} key: {{ tpl $value.valueFrom.configMapKeyRef.key $ | quote }} {{- end }} {{- end }} {{- end }} # Probe values are rendered through tpl (see values.yaml for the # defaults and why the probes send a Host header). livenessProbe: {{- tpl (include "patchmon.server.livenessProbe" (dict "given" .Values.patchmon.server.livenessProbe "root" $)) . | nindent 12 }} readinessProbe: {{- tpl (include "patchmon.server.readinessProbe" (dict "given" .Values.patchmon.server.readinessProbe "root" $)) . | nindent 12 }} startupProbe: {{- tpl (include "patchmon.server.startupProbe" (dict "given" .Values.patchmon.server.startupProbe "root" $)) . | nindent 12 }} resources: {{- include "patchmon.server.effectiveResources" .Values.patchmon.server.resources | nindent 12 }} volumeMounts: # The image is stateless, but the Go server needs a writable /tmp # for scratch files with a read-only root filesystem. - name: tmp mountPath: /tmp {{- if .Values.patchmon.guacd.enabled }} - name: {{ .Release.Name }}-{{ .Chart.Name }}-guacd image: {{ .Values.patchmon.guacd.image }} imagePullPolicy: IfNotPresent {{- if .Values.patchmon.guacd.env }} env: {{- range $value := .Values.patchmon.guacd.env }} {{- if $value.value }} - name: {{ $value.name | quote }} value: {{ tpl $value.value $ | quote }} {{- else if $value.valueFrom }} {{- if $value.valueFrom.secretKeyRef }} - name: {{ $value.name }} valueFrom: secretKeyRef: name: {{ tpl $value.valueFrom.secretKeyRef.name $ | quote }} key: {{ tpl $value.valueFrom.secretKeyRef.key $ | quote }} {{- else if $value.valueFrom.configMapKeyRef }} - name: {{ $value.name }} valueFrom: configMapKeyRef: name: {{ tpl $value.valueFrom.configMapKeyRef.name $ | quote }} key: {{ tpl $value.valueFrom.configMapKeyRef.key $ | quote }} {{- end }} {{- end }} {{- end }} {{- end }} securityContext: {{- include "patchmon.guacd.containerSecurityContext" .Values.patchmon.guacd.securityContext | nindent 12 }} ports: - containerPort: 4822 protocol: TCP name: guacd livenessProbe: {{- tpl (include "patchmon.guacd.livenessProbe" .Values.patchmon.guacd.livenessProbe) . | nindent 12 }} readinessProbe: {{- tpl (include "patchmon.guacd.readinessProbe" .Values.patchmon.guacd.readinessProbe) . | nindent 12 }} startupProbe: {{- tpl (include "patchmon.guacd.startupProbe" .Values.patchmon.guacd.startupProbe) . | nindent 12 }} resources: {{- include "patchmon.guacd.effectiveResources" .Values.patchmon.guacd.resources | nindent 12 }} volumeMounts: - name: guacd-tmp mountPath: /tmp {{- end }} restartPolicy: Always volumes: - name: tmp emptyDir: {} {{- if .Values.patchmon.guacd.enabled }} - name: guacd-tmp emptyDir: {} {{- end }}