Three changes, all about values that do not do what they promise: 1. values.schema.json (#68): additionalProperties: false on every chart-owned object level, so a key the chart does not read is rejected at render time instead of being silently ignored. 2. Ingress gate (#93): the Ingress template is wrapped in {{- if .Values.ingress.enabled }} and the key is added to values.yaml with default true, so behaviour is unchanged. ingress.domain is NOT a pure Ingress value here - it is also the app's public base URL (NEXT_PUBLIC_BASE_URL). Gating alone would therefore have introduced a new silent failure: with the Ingress switched off and no domain, the deployment rendered value: "https://" and every generated link would be broken. The deployment's read of the value is now required(), so that case fails loudly. Only clusterIssuer actually becomes unnecessary when the Ingress is off. 3. Null-safety for hardening, probes and resources (#99): an erased block fell back to "securityContext: null" (unhardened), a vanished probe or a container without resource accounting. Restoring the pod context matters especially here, because its fsGroup is what makes the Next.js cache emptyDir group-writable for the container. rallly.cache is deliberately NOT null-safe: cache.path is required(), so an erased block fails loudly and belongs to the loud class #99 excludes. Apart from an added comment, the rendered manifest is unchanged.
172 lines
7.2 KiB
YAML
172 lines
7.2 KiB
YAML
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-deployment
|
|
labels:
|
|
app: {{ .Release.Name }}-{{ .Chart.Name }}-deployment
|
|
spec:
|
|
replicas: {{ include "rallly.replicas" (dict "scaleDown" .Values.scaleDown "replicas" .Values.rallly.replicas) }}
|
|
selector:
|
|
matchLabels:
|
|
app: {{ .Release.Name }}-{{ .Chart.Name }}-deployment
|
|
template:
|
|
metadata:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-deployment
|
|
labels:
|
|
app: {{ .Release.Name }}-{{ .Chart.Name }}-deployment
|
|
spec:
|
|
automountServiceAccountToken: false
|
|
securityContext:
|
|
{{- include "rallly.podSecurityContext" .Values.rallly.securityContext | nindent 8 }}
|
|
containers:
|
|
- name: {{ .Release.Name }}-{{ .Chart.Name }}-deployment
|
|
image: "lukevella/rallly:{{ .Chart.AppVersion }}"
|
|
imagePullPolicy: IfNotPresent
|
|
env:
|
|
# ingress.domain is not a pure Ingress value: it is also the app's
|
|
# public base URL, so it stays required even when the Ingress is
|
|
# switched off (an empty value would render "https://" and break
|
|
# every generated link silently).
|
|
- name: NEXT_PUBLIC_BASE_URL
|
|
value: "https://{{ required "A Domain/Host must be provided (ingress.domain)" .Values.ingress.domain }}"
|
|
- name: SECRET_PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-secret
|
|
key: secret-key
|
|
- name: SUPPORT_EMAIL
|
|
value: "{{ required "A Support-Email must be provided" .Values.rallly.supportEmail }}"
|
|
{{- if .Values.rallly.smtp.enabled }}
|
|
- name: NOREPLY_EMAIL
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-smtp-secret
|
|
key: no-reply-email
|
|
- name: NOREPLY_EMAIL_NAME
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-smtp-secret
|
|
key: no-reply-email-name
|
|
- name: SMTP_HOST
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-smtp-secret
|
|
key: host
|
|
- name: SMTP_PORT
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-smtp-secret
|
|
key: port
|
|
- name: SMTP_SECURE
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-smtp-secret
|
|
key: secure
|
|
- name: SMTP_USER
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-smtp-secret
|
|
key: user
|
|
- name: SMTP_PWD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-smtp-secret
|
|
key: password
|
|
- name: SMTP_REJECT_UNAUTHORIZED
|
|
value: "{{ .Values.rallly.smtp.rejectUnauthorized }}"
|
|
- name: SMTP_TLS_SERVERNAME
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-smtp-secret
|
|
key: tls-servername
|
|
{{- end }}
|
|
- name: EMAIL_LOGIN_ENABLED
|
|
value: "false"
|
|
- name: REGISTRATION_ENABLED
|
|
value: "false"
|
|
- name: OIDC_NAME
|
|
value: "{{ .Values.rallly.oidc.name }}"
|
|
- name: OIDC_NAME_CLAIM_PATH
|
|
value: "{{ .Values.rallly.oidc.nameClaimPath }}"
|
|
- name: OIDC_EMAIL_CLAIM_PATH
|
|
value: "{{ .Values.rallly.oidc.emailClaimPath }}"
|
|
- name: OIDC_PICTURE_CLAIM_PATH
|
|
value: "{{ .Values.rallly.oidc.pictureClaimPath }}"
|
|
- name: OIDC_DISCOVERY_URL
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-oidc-secret
|
|
key: discovery-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: ALLOWED_EMAILS
|
|
value: "{{ .Values.rallly.allowedEmails }}"
|
|
- name: INITIAL_ADMIN_EMAIL
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-secret
|
|
key: initial-admin-email
|
|
- name: DATABASE_URL
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-database-secret
|
|
key: database-url
|
|
# TODO: Add Storage Configuration
|
|
{{- range $value := .Values.rallly.env }}
|
|
{{- if $value.value }}
|
|
- name: {{ $value.name }}
|
|
value: {{ tpl $value.value $ }}
|
|
{{- else if $value.valueFrom }}
|
|
{{- if $value.valueFrom.secretKeyRef }}
|
|
- name: {{ $value.name }}
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: {{ tpl $value.valueFrom.secretKeyRef.name $ }}
|
|
key: {{ tpl $value.valueFrom.secretKeyRef.key $ }}
|
|
{{- else if $value.valueFrom.configMapKeyRef }}
|
|
- name: {{ $value.name }}
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: {{ tpl $value.valueFrom.configMapKeyRef.name $ }}
|
|
key: {{ tpl $value.valueFrom.configMapKeyRef.key $ }}
|
|
{{- end }}
|
|
{{- end }}
|
|
{{- end }}
|
|
ports:
|
|
- containerPort: 3000
|
|
protocol: TCP
|
|
name: http
|
|
livenessProbe:
|
|
{{- include "rallly.livenessProbe" .Values.rallly.livenessProbe | nindent 12 }}
|
|
readinessProbe:
|
|
{{- include "rallly.readinessProbe" .Values.rallly.readinessProbe | nindent 12 }}
|
|
startupProbe:
|
|
{{- include "rallly.startupProbe" .Values.rallly.startupProbe | nindent 12 }}
|
|
resources:
|
|
{{- include "rallly.effectiveResources" .Values.rallly.resources | nindent 12 }}
|
|
securityContext:
|
|
{{- include "rallly.containerSecurityContext" .Values.rallly.securityContext | nindent 12 }}
|
|
volumeMounts:
|
|
# Next.js writes prerendered pages and optimized images into its
|
|
# cache directory; with a read-only root filesystem this must be a
|
|
# writable volume (see rallly.cache in values.yaml).
|
|
- name: next-cache
|
|
mountPath: {{ required "A cache path must be provided (rallly.cache.path)" .Values.rallly.cache.path | quote }}
|
|
volumes:
|
|
- name: next-cache
|
|
{{- if .Values.rallly.cache.sizeLimit }}
|
|
emptyDir:
|
|
sizeLimit: {{ .Values.rallly.cache.sizeLimit | quote }}
|
|
{{- else }}
|
|
emptyDir: {}
|
|
{{- end }}
|
|
restartPolicy: Always
|