Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Next Gen Chart #132

Merged
merged 16 commits into from
Feb 14, 2025
951 changes: 696 additions & 255 deletions README.md

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions charts/n8n/Chart.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
dependencies:
- name: redis
repository: https://charts.bitnami.com/bitnami
version: 18.6.1
digest: sha256:679512a5d6167cd529b9b6d861a6605f62683c3497b8f920fc344dd00bf0ba82
generated: "2024-06-30T21:39:40.024252056+02:00"
- name: valkey
repository: oci://registry-1.docker.io/bitnamicharts
version: 2.2.3
digest: sha256:3bed83ffaec482e8e31eae77f966ecbd95258b6124ced0824d825805dc23e197
generated: "2025-01-18T14:00:37.663128+01:00"
14 changes: 7 additions & 7 deletions charts/n8n/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: v2
name: n8n
version: 0.25.2
appVersion: 1.62.5
version: 1.0.0
appVersion: 1.76.1
type: application
description: "A Kubernetes Helm chart for n8n a free and open fair-code licensed node based Workflow Automation Tool. Easily automate tasks across different services."
home: https://github.com/8gears/n8n-helm-chart
Expand All @@ -25,13 +25,13 @@ maintainers:
url: https://github.com/n8n-io

dependencies:
- name: redis
version: 18.6.1
repository: https://charts.bitnami.com/bitnami
- name: valkey
version: 2.2.3
repository: oci://registry-1.docker.io/bitnamicharts
condition: redis.enabled
Comment on lines +28 to 31
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

⚠️ Potential issue

⚠️ Review comment is correct and reveals additional concerns

The verification confirms both issues and reveals more concerns:

  • Valkey is not advertised as a Redis-compatible replacement but a separate key/value store
  • The redis.enabled condition is misleading and should be valkey.enabled
  • Migration documentation is crucial as this is not a drop-in replacement
  • The entire dependency change from Redis to Valkey needs architectural review as they are different products
🔗 Analysis chain

⚠️ Valkey integration requires additional work

The Redis to Valkey migration has several issues:

  1. The condition redis.enabled should be renamed to valkey.enabled
  2. Migration documentation is needed
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check Valkey's compatibility with Redis
curl -s "https://raw.githubusercontent.com/bitnami/charts/main/bitnami/valkey/values.yaml" | head -n 50

Length of output: 2117


Script:

#!/bin/bash
# Search for Redis-related content in Valkey's full values.yaml and README
echo "=== Checking values.yaml for Redis mentions ==="
curl -s "https://raw.githubusercontent.com/bitnami/charts/main/bitnami/valkey/values.yaml" | grep -i "redis" || echo "No Redis mentions found"

echo -e "\n=== Checking README for Redis compatibility or migration info ==="
curl -s "https://raw.githubusercontent.com/bitnami/charts/main/bitnami/valkey/README.md" | grep -i -A 5 -B 5 "redis" || echo "No Redis mentions found"

echo -e "\n=== Checking if Valkey is meant to be Redis compatible ==="
curl -s "https://raw.githubusercontent.com/bitnami/charts/main/bitnami/valkey/Chart.yaml" | grep -i "description" -A 2

Length of output: 2656

annotations:
artifacthub.io/prerelease: "false"
artifacthub.io/prerelease: "true"
# supported kinds are added, changed, deprecated, removed, fixed and security.
artifacthub.io/changes: |
- kind: changed
description: "Updated application to version 1.62.5"
description: "Major chart redesign and also update to n8n version 1.74.1. This version is not compatible with the previous version. Please read the release notes for more details."
8 changes: 4 additions & 4 deletions charts/n8n/templates/NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
{{- else if contains "NodePort" (default "ClusterIP" .Values.main.service.type) }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "n8n.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
{{- else if contains "LoadBalancer" (default "ClusterIP" .Values.main.service.type) }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "n8n.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "n8n.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
echo http://$SERVICE_IP:{{ .Values.main.service.port }}
{{- else if contains "ClusterIP" (default "ClusterIP" .Values.main.service.type) }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "n8n.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
Expand Down
113 changes: 38 additions & 75 deletions charts/n8n/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -50,92 +50,55 @@ app.kubernetes.io/name: {{ include "n8n.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "n8n.deploymentPodEnvironments" -}}
{{- range $key, $value := .Values.extraEnv }}
- name: {{ $key }}
value: {{ $value | quote}}
{{ end }}
{{- range $key, $value := .Values.extraEnvSecrets }}
- name: {{ $key }}
valueFrom:
secretKeyRef:
name: {{ $value.name | quote }}
key: {{ $value.key | quote }}
{{ end }}
- name: "N8N_PORT" #! we better set the port once again as ENV Var, see: https://community.n8n.io/t/default-config-is-not-set-or-the-port-to-be-more-precise/3158/3?u=vad1mo
value: {{ get .Values.config "port" | default "5678" | quote }}
{{- if .Values.n8n.encryption_key }}
- name: "N8N_ENCRYPTION_KEY"
valueFrom:
secretKeyRef:
key: N8N_ENCRYPTION_KEY
name: {{ include "n8n.fullname" . }}
{{- end }}
{{- if or .Values.config .Values.secret }}
- name: "N8N_CONFIG_FILES"
value: {{ include "n8n.configFiles" . | quote }}
{{ end }}
{{- if .Values.scaling.enabled }}
- name: "QUEUE_BULL_REDIS_HOST"
{{- if .Values.scaling.redis.host }}
value: "{{ .Values.scaling.redis.host }}"
{{ else }}
value: "{{ .Release.Name }}-redis-master"
{{ end }}
- name: "EXECUTIONS_MODE"
value: "queue"
{{ end }}
{{- if .Values.scaling.redis.password }}
- name: "QUEUE_BULL_REDIS_PASSWORD"
value: "{{ .Values.scaling.redis.password }}"
{{ end }}
{{- if .Values.scaling.webhook.enabled }}
- name: "N8N_DISABLE_PRODUCTION_MAIN_PROCESS"
value: "true"
{{ end }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{/* Create the name of the service account to use */}}
{{- define "n8n.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "n8n.fullname" .) .Values.serviceAccount.name }}
{{- if .Values.main.serviceAccount.create }}
{{- default (include "n8n.fullname" .) .Values.main.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- default "default" .Values.main.serviceAccount.name }}
{{- end }}
{{- end }}

{{/* Create a list of config files for n8n */}}
{{- define "n8n.configFiles" -}}
{{- $conf_val := "" }}
{{- $sec_val := "" }}
{{- $separator := "" }}
{{- if .Values.config }}
{{- $conf_val = "/n8n-config/config.json" }}
{{- end }}
{{- if or .Values.secret .Values.existingSecret }}
{{- $sec_val = "/n8n-secret/secret.json" }}
{{- end }}
{{- if and .Values.config (or .Values.secret .Values.existingSecret) }}
{{- $separator = "," }}
{{- end }}
{{- print $conf_val $separator $sec_val }}
{{- end }}


{{/* PVC existing, emptyDir, Dynamic */}}
{{- define "n8n.pvc" -}}
{{- if or (not .Values.persistence.enabled) (eq .Values.persistence.type "emptyDir") -}}
{{- if or (not .Values.main.persistence.enabled) (eq .Values.main.persistence.type "emptyDir") -}}
emptyDir: {}
{{- else if and .Values.persistence.enabled .Values.persistence.existingClaim -}}
{{- else if and .Values.main.persistence.enabled .Values.main.persistence.existingClaim -}}
persistentVolumeClaim:
claimName: {{ .Values.persistence.existingClaim }}
{{- else if and .Values.persistence.enabled (eq .Values.persistence.type "dynamic") -}}
claimName: {{ .Values.main.persistence.existingClaim }}
{{- else if and .Values.main.persistence.enabled (eq .Values.main.persistence.type "dynamic") -}}
persistentVolumeClaim:
claimName: {{ include "n8n.fullname" . }}
{{- end }}
{{- end }}


{{/* Create environment variables from yaml tree */}}
{{- define "toEnvVars" -}}
{{- $prefix := "" }}
{{- if .prefix }}
{{- $prefix = printf "%s_" .prefix }}
{{- end }}
{{- range $key, $value := .values }}
{{- if kindIs "map" $value -}}
{{- dict "values" $value "prefix" (printf "%s%s" $prefix ($key | upper)) "isSecret" $.isSecret | include "toEnvVars" -}}
{{- else -}}
{{- if $.isSecret -}}
{{ $prefix }}{{ $key | upper }}: {{ $value | b64enc }}{{ "\n" }}
{{- else -}}
{{ $prefix }}{{ $key | upper }}: {{ $value | quote }}{{ "\n" }}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end }}


{{/* Validate Redis configuration when webhooks are enabled*/}}
{{- define "n8n.validateRedis" -}}
{{- if and .Values.webhook.enabled (not .Values.redis.enabled) -}}
{{- fail "Webhook processes rely on Redis. Please set redis.enabled=true when webhook.enabled=true" -}}
{{- end -}}
{{- end -}}


10 changes: 10 additions & 0 deletions charts/n8n/templates/configmap.webhook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{{- if .Values.webhook.config }}
apiVersion: v1
kind: ConfigMap
metadata:
name: webhook-config-{{ include "n8n.fullname" . }}
labels:
{{- include "n8n.labels" . | nindent 4 }}
data:
{{- include "toEnvVars" (dict "values" .Values.webhook.config "prefix" "") | nindent 2 }}
{{- end }}
8 changes: 3 additions & 5 deletions charts/n8n/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
{{- if .Values.config }}
{{- if .Values.main.config }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "n8n.fullname" . }}
name: app-config-{{ include "n8n.fullname" . }}
labels:
{{- include "n8n.labels" . | nindent 4 }}
data:
config.json: |
{{ .Values.config | toPrettyJson | indent 4 }}

{{- include "toEnvVars" (dict "values" .Values.main.config "prefix" "") | nindent 2 }}
{{- end }}
126 changes: 126 additions & 0 deletions charts/n8n/templates/deployment.webhook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
{{- if .Values.webhook.enabled }}
{{- /* Validate Redis configuration */}}
{{- include "n8n.validateRedis" . }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "n8n.fullname" . }}-webhook
labels:
{{- include "n8n.labels" . | nindent 4 }}
spec:
{{- if not .Values.webhook.autoscaling.enabled }}
replicas: {{ .Values.webhook.replicaCount }}
{{- end }}
strategy:
type: {{ .Values.webhook.deploymentStrategy.type }}
{{- if eq .Values.webhook.deploymentStrategy.type "RollingUpdate" }}
rollingUpdate:
maxSurge: {{ default "25%" .Values.webhook.deploymentStrategy.maxSurge }}
maxUnavailable: {{ default "25%" .Values.webhook.deploymentStrategy.maxUnavailable }}
{{- end }}
selector:
matchLabels:
{{- include "n8n.selectorLabels" . | nindent 6 }}
app.kubernetes.io/type: webhook
template:
metadata:
annotations:
checksum/config: {{ print .Values.webhook .Values.main | sha256sum }}
{{- with .Values.webhook.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "n8n.selectorLabels" . | nindent 8 }}
app.kubernetes.io/type: webhook
{{- if .Values.webhook.podLabels }}
{{ toYaml .Values.webhook.podLabels | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "n8n.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.webhook.podSecurityContext | nindent 8 }}
{{- if .Values.webhook.initContainers }}
initContainers:
{{ tpl (toYaml .Values.webhook.initContainers) . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}-webhook
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if .Values.webhook.command }}
command:
{{- toYaml .Values.webhook.command | nindent 12 }}
{{- else }}
command: ["n8n"]
{{- end }}
{{- if .Values.webhook.commandArgs }}
args:
{{- toYaml .Values.webhook.commandArgs | nindent 12 }}
{{- else }}
args:
- "webhook"
{{- end }}
ports:
- name: http
containerPort: {{ get .Values.webhook.config "port" | default 5678 }}
protocol: TCP
{{- with .Values.webhook.livenessProbe }}
livenessProbe:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.webhook.readinessProbe }}
readinessProbe:
{{- toYaml . | nindent 12 }}
{{- end }}
envFrom:
{{- if .Values.main.config }}
- configMapRef:
name: app-config-{{ include "n8n.fullname" . }}
{{- end }}
{{- if .Values.main.secret }}
- secretRef:
name: app-secret-{{ include "n8n.fullname" . }}
{{- end }}
{{- if .Values.webhook.config }}
- configMapRef:
name: webhook-config-{{ include "n8n.fullname" . }}
{{- end }}
{{- if .Values.webhook.secret }}
- secretRef:
name: webhook-secret-{{ include "n8n.fullname" . }}
{{- end }}

env: {{ not (empty .Values.webhook.extraEnv) | ternary nil "[]" }}
{{- range $key, $value := .Values.webhook.extraEnv }}
- name: {{ $key }}
{{- toYaml $value | nindent 14 }}
{{- end }}
lifecycle:
{{- toYaml .Values.webhook.lifecycle | nindent 12 }}
securityContext:
{{- toYaml .Values.webhook.securityContext | nindent 12 }}
resources:
{{- toYaml .Values.webhook.resources | nindent 12 }}
volumeMounts:
- name: data
mountPath: /home/node/.n8n
{{- with .Values.webhook.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.webhook.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.webhook.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
volumes:
- name: "data"
{{ include "n8n.pvc" . }}
{{- end }}
Loading
Loading