Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
900756d
feat(helm): add Redis auth support with password bootstrap
sebastianiv21 Jun 4, 2026
3b44511
Merge branch 'release' into claude/strange-colden-2a0830
sebastianiv21 Jun 4, 2026
86564b9
Merge branch 'release' into claude/strange-colden-2a0830
sebastianiv21 Jun 4, 2026
964a971
chore: bump helm chart version to v3.8.2
sebastianiv21 Jun 9, 2026
812db5c
chore(client): batch resolution upgrades to fix 22 Dependabot alerts …
subrata71 Jun 5, 2026
a1dfc27
chore(plugins): upgrade mssql-jdbc to fix Dependabot alert (#41880)
subrata71 Jun 8, 2026
f334e14
chore(widgets): upgrade tinymce from 6.8.5 to 7.9.3 to fix 8 XSS aler…
subrata71 Jun 9, 2026
b649f1d
chore(client): add shell-quote 1.8.4 resolution to fix critical alert…
subrata71 Jun 9, 2026
dfca3cd
chore(helm): replace README with helm-docs generated file to keep val…
sebastianiv21 Jun 9, 2026
2c81821
chore(deps): bump golang from 1.26.3-alpine to 1.26.4-alpine in /depl…
dependabot[bot] Jun 9, 2026
ff71415
feat(helm): add Redis auth support with password bootstrap
sebastianiv21 Jun 9, 2026
58ffcdc
Merge branch 'release' into claude/strange-colden-2a0830
sebastianiv21 Jun 9, 2026
7788231
chore: generate README
sebastianiv21 Jun 9, 2026
4e79144
chore: add documentation comments for Redis auth parameters
sebastianiv21 Jun 9, 2026
ddf0389
fix(helm): guard against unsupported redis.auth.password configurations
wyattwalter Jun 24, 2026
319b4c7
fix(helm): skip redis-init-container REDISCLI_AUTH on self-managed pa…
wyattwalter Jun 24, 2026
d279bea
docs(helm): record redis.auth.password self-managed-path invariants i…
wyattwalter Jun 24, 2026
f175f91
Revert "docs(helm): record redis.auth.password self-managed-path inva…
wyattwalter Jun 25, 2026
cf9fa0d
Merge pull request #41924 from appsmithorg/fm/redis-pw-guard-v3
wyattwalter Jun 25, 2026
c659b7b
fix(helm): derive redis master host from subchart fullname + tests
sebastianiv21 Jun 26, 2026
c354051
fix(helm): make redisMasterHost self-contained so unittest CI passes
sebastianiv21 Jun 26, 2026
bc002b8
Revert "fix(helm): make redisMasterHost self-contained so unittest CI…
sebastianiv21 Jun 26, 2026
9921ef3
Merge branch 'release' into claude/strange-colden-2a0830
sebastianiv21 Jun 26, 2026
134bc41
Merge branch 'release' into claude/strange-colden-2a0830
wyattwalter Jul 6, 2026
8ae0b13
chore(helm): bump chart version to 3.9.0
sebastianiv21 Jul 6, 2026
5b16282
test(helm): update snapshot for chart version 3.9.0
sebastianiv21 Jul 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deploy/helm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ sources:
- https://github.com/appsmithorg/appsmith
home: https://www.appsmith.com/
icon: https://assets.appsmith.com/appsmith-icon.png
version: 3.8.1
version: 3.8.2
dependencies:
- condition: redis.enabled
name: redis
Expand Down
27 changes: 27 additions & 0 deletions deploy/helm/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,33 @@ Uses existing secret if provided, otherwise derives from the CR name
{{- end -}}
{{- end -}}

{{/*
Redis: password secret name
Uses existing secret if provided, otherwise derives "{release}-redis-secret"
*/}}
{{- define "appsmith.redisSecretName" -}}
{{- .Values.redis.auth.existingSecret | default (printf "%s-redis-secret" .Release.Name) -}}
{{- end -}}

{{/*
Redis: master service hostname (FQDN inside the cluster).
Derived from the release name to stay uniform with the chart's other components.
Assumes the release name does not contain "redis" (otherwise the Bitnami subchart
collapses its fullname to just the release name and this host would not match).
*/}}
{{- define "appsmith.redisMasterHost" -}}
{{- printf "%s-redis-master.%s.svc.cluster.local" .Release.Name (include "appsmith.namespace" .) -}}
{{- end -}}
Comment thread
sebastianiv21 marked this conversation as resolved.

{{/*
Redis: kubectl image used by the password-init Job.
Kept independent from the MongoDB equivalent so the two bootstraps don't share config.
*/}}
{{- define "appsmith.redisPasswordInitImage" -}}
{{- $img := .Values.redisAuth.passwordInit.image -}}
{{- printf "%s/%s:%s" $img.registry $img.repository $img.tag -}}
{{- end -}}

{{/*
Renders a value that contains template.
*/}}
Expand Down
4 changes: 2 additions & 2 deletions deploy/helm/templates/configMap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ data:
{{- end }}

{{- if and (eq "APPSMITH_REDIS_URL" $key) ( not $value) }}
{{- if $.Values.redis.enabled }}
{{ $key }}: redis://{{ $releaseName }}-redis-master.{{ $nameSpace }}.svc.cluster.local:6379
{{- if and $.Values.redis.enabled (not $.Values.redis.auth.enabled) }}
{{ $key }}: redis://{{ include "appsmith.redisMasterHost" $ }}:6379
{{- end }}
{{- end }}

Expand Down
25 changes: 24 additions & 1 deletion deploy/helm/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,15 @@ spec:
{{- else }}
image: "{{ .Values.redis.image.registry }}/{{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }}"
{{- end }}
command: ['sh', '-c', "until redis-cli -h {{.Release.Name}}-redis-master.{{.Release.Namespace}}.svc.cluster.local ping ; do echo waiting for redis; sleep 2; done"]
command: ['sh', '-c', "until redis-cli -h {{ include "appsmith.redisMasterHost" . }} ping ; do echo waiting for redis; sleep 2; done"]
{{- if .Values.redis.auth.enabled }}
env:
- name: REDISCLI_AUTH
valueFrom:
secretKeyRef:
name: {{ include "appsmith.redisSecretName" . }}
key: {{ .Values.redis.auth.existingSecretPasswordKey }}
{{- end }}
{{- end }}
{{- if .Values.mongodb.enabled }}
- name: mongo-init-container
Expand Down Expand Up @@ -175,6 +183,21 @@ spec:
name: {{ include "appsmith.mongoOperatorSecretName" . }}
key: connectionString.standardSrv
{{- end }}
{{- if and .Values.redis.enabled .Values.redis.auth.enabled (not .Values.applicationConfig.APPSMITH_REDIS_URL) }}
# Assemble the authenticated Redis URL for the bundled subchart. Skipped when the
# user supplied applicationConfig.APPSMITH_REDIS_URL (which is honored via the
# ConfigMap) — an explicit env entry here would otherwise take precedence over
# envFrom and silently override it. The password is pulled from the Secret and
# injected by reference, so the cleartext never lands in the ConfigMap; order
# matters — the password var must precede the URL that references it via $(VAR).
- name: APPSMITH_REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "appsmith.redisSecretName" . }}
key: {{ .Values.redis.auth.existingSecretPasswordKey }}
- name: APPSMITH_REDIS_URL
value: "redis://:$(APPSMITH_REDIS_PASSWORD)@{{ include "appsmith.redisMasterHost" . }}:6379"
{{- end }}
envFrom:
- configMapRef:
name: {{ include "appsmith.fullname" . }}
Expand Down
130 changes: 130 additions & 0 deletions deploy/helm/templates/hooks/redis.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
{{/*
Creates the Redis password secret via a pre-install/pre-upgrade Job when the
bundled redis subchart is enabled with auth on.

The Job is idempotent: if the secret already exists, it exits without change.
This keeps the password stable across Helm upgrades and ArgoCD re-syncs —
unlike a template-based `randAlphaNum` approach, which changes on every render
and would either lock clients out or force an ArgoCD ignoreDifferences rule.

The runtime "secret already exists -> exit 0" check is also the migration and
bring-your-own-secret guard: an upgrade of an install that already has the
secret (or a user who pre-created their own) is left untouched.

The resulting Secret has no Helm release labels/annotations and no
ownerReferences, so ArgoCD does not track or diff it.
*/}}
{{- if and .Values.redis.enabled .Values.redis.auth.enabled }}
{{- $secretName := include "appsmith.redisSecretName" . -}}
{{- $passwordKey := .Values.redis.auth.existingSecretPasswordKey -}}
{{- $jobName := printf "%s-redis-password-init" (include "appsmith.fullname" .) | trunc 63 | trimSuffix "-" -}}
{{- $namespace := include "appsmith.namespace" . -}}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ $jobName }}
namespace: {{ $namespace }}
labels:
{{- include "appsmith.labels" . | nindent 4 }}
annotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-weight: "-5"
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ $jobName }}
namespace: {{ $namespace }}
labels:
{{- include "appsmith.labels" . | nindent 4 }}
annotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-weight: "-5"
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
rules:
# Check whether the password secret already exists (scoped to one name).
- apiGroups: [""]
resources: ["secrets"]
resourceNames: [{{ $secretName | quote }}]
verbs: ["get"]
# Create it if it doesn't. resourceNames can't scope `create` (the name
# is in the request body, not the URL), so this is namespace-scoped.
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ $jobName }}
namespace: {{ $namespace }}
labels:
{{- include "appsmith.labels" . | nindent 4 }}
annotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-weight: "-5"
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
subjects:
- kind: ServiceAccount
name: {{ $jobName }}
namespace: {{ $namespace }}
roleRef:
kind: Role
name: {{ $jobName }}
apiGroup: rbac.authorization.k8s.io
---
apiVersion: batch/v1
kind: Job
metadata:
name: {{ $jobName }}
namespace: {{ $namespace }}
labels:
{{- include "appsmith.labels" . | nindent 4 }}
annotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-weight: "0"
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
spec:
ttlSecondsAfterFinished: 60
backoffLimit: 3
template:
metadata:
labels:
{{- include "appsmith.labels" . | nindent 8 }}
spec:
serviceAccountName: {{ $jobName }}
restartPolicy: Never
{{- if .Values.image.pullSecrets }}
imagePullSecrets:
- name: {{ .Values.image.pullSecrets }}
{{- end }}
containers:
- name: create-password
image: {{ include "appsmith.redisPasswordInitImage" . | quote }}
imagePullPolicy: {{ .Values.redisAuth.passwordInit.image.pullPolicy }}
command:
- /bin/sh
- -c
- |
set -eu
SECRET_NAME={{ $secretName | quote }}
NAMESPACE={{ $namespace | quote }}
PASSWORD_KEY={{ $passwordKey | quote }}
if kubectl -n "$NAMESPACE" get secret "$SECRET_NAME" >/dev/null 2>&1; then
echo "Secret $SECRET_NAME already exists; leaving it untouched."
exit 0
fi
PASSWORD=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 24)
kubectl -n "$NAMESPACE" create secret generic "$SECRET_NAME" \
--from-literal="$PASSWORD_KEY"="$PASSWORD"
echo "Created secret $SECRET_NAME."
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
capabilities:
drop: ["ALL"]
{{- end }}
Loading
Loading