From fc182fa083aba3eea843e421711e6fa944be1e2f Mon Sep 17 00:00:00 2001 From: dvirlabs <114520947+dvirlabs@users.noreply.github.com> Date: Tue, 26 May 2026 13:25:23 +0300 Subject: [PATCH] Add n8n --- argocd-apps/n8n.yaml | 38 +++++++++ charts/n8n/Chart.yaml | 6 ++ charts/n8n/templates/_helpers.tpl | 49 +++++++++++ charts/n8n/templates/configmap.yaml | 17 ++++ charts/n8n/templates/deployment.yaml | 121 +++++++++++++++++++++++++++ charts/n8n/templates/ingress.yaml | 45 ++++++++++ charts/n8n/templates/pvc.yaml | 15 ++++ charts/n8n/templates/service.yaml | 15 ++++ charts/n8n/values.yaml | 74 ++++++++++++++++ manifests/n8n/values.yaml | 49 +++++++++++ 10 files changed, 429 insertions(+) create mode 100644 argocd-apps/n8n.yaml create mode 100644 charts/n8n/Chart.yaml create mode 100644 charts/n8n/templates/_helpers.tpl create mode 100644 charts/n8n/templates/configmap.yaml create mode 100644 charts/n8n/templates/deployment.yaml create mode 100644 charts/n8n/templates/ingress.yaml create mode 100644 charts/n8n/templates/pvc.yaml create mode 100644 charts/n8n/templates/service.yaml create mode 100644 charts/n8n/values.yaml create mode 100644 manifests/n8n/values.yaml diff --git a/argocd-apps/n8n.yaml b/argocd-apps/n8n.yaml new file mode 100644 index 0000000..8757325 --- /dev/null +++ b/argocd-apps/n8n.yaml @@ -0,0 +1,38 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: n8n + namespace: argocd + labels: + env: dev-tools +spec: + project: dev-tools + source: + repoURL: ssh://git@gitea-ssh.dev-tools.svc.cluster.local:2222/dvirlabs/dev-tools.git + targetRevision: HEAD + path: charts/n8n + helm: + valueFiles: + - ../../manifests/n8n/values.yaml + destination: + server: https://kubernetes.default.svc + namespace: dev-tools + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - PrunePropagationPolicy=foreground + - RespectIgnoreDifferences=true + ignoreDifferences: + - kind: PersistentVolumeClaim + namespace: dev-tools + jsonPointers: + - /status + - /spec/volumeName + - kind: Service + namespace: dev-tools + jsonPointers: + - /spec/clusterIP + - /spec/clusterIPs diff --git a/charts/n8n/Chart.yaml b/charts/n8n/Chart.yaml new file mode 100644 index 0000000..5311751 --- /dev/null +++ b/charts/n8n/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +appVersion: 1.0.0 +description: A Helm chart to deploy n8n workflow automation +name: n8n +type: application +version: 1.0.0 diff --git a/charts/n8n/templates/_helpers.tpl b/charts/n8n/templates/_helpers.tpl new file mode 100644 index 0000000..33be11a --- /dev/null +++ b/charts/n8n/templates/_helpers.tpl @@ -0,0 +1,49 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "n8n.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "n8n.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "n8n.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.AppVersion | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "n8n.labels" -}} +helm.sh/chart: {{ include "n8n.chart" . }} +{{ include "n8n.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "n8n.selectorLabels" -}} +app.kubernetes.io/name: {{ include "n8n.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/n8n/templates/configmap.yaml b/charts/n8n/templates/configmap.yaml new file mode 100644 index 0000000..1f69d8a --- /dev/null +++ b/charts/n8n/templates/configmap.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "n8n.fullname" . }} + labels: + {{- include "n8n.labels" . | nindent 4 }} +data: + N8N_HOST: {{ .Values.config.N8N_HOST | quote }} + N8N_PROTOCOL: {{ .Values.config.N8N_PROTOCOL | quote }} + WEBHOOK_URL: {{ .Values.config.WEBHOOK_URL | quote }} + GENERIC_TIMEZONE: {{ .Values.config.GENERIC_TIMEZONE | quote }} + N8N_SECURE_COOKIE: {{ .Values.config.N8N_SECURE_COOKIE | quote }} + DB_TYPE: {{ .Values.config.DB_TYPE | quote }} + DB_SQLITE_FILE: {{ .Values.config.DB_SQLITE_FILE | quote }} + {{- with .Values.configData }} + {{- toYaml . | nindent 2 }} + {{- end }} diff --git a/charts/n8n/templates/deployment.yaml b/charts/n8n/templates/deployment.yaml new file mode 100644 index 0000000..803af85 --- /dev/null +++ b/charts/n8n/templates/deployment.yaml @@ -0,0 +1,121 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "n8n.fullname" . }} + labels: + {{- include "n8n.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount | default 1 }} + selector: + matchLabels: + {{- include "n8n.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + labels: + {{- include "n8n.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 5678 + protocol: TCP + env: + # N8N configuration from values + - name: N8N_HOST + valueFrom: + configMapKeyRef: + name: {{ include "n8n.fullname" . }} + key: N8N_HOST + - name: N8N_PROTOCOL + valueFrom: + configMapKeyRef: + name: {{ include "n8n.fullname" . }} + key: N8N_PROTOCOL + - name: WEBHOOK_URL + valueFrom: + configMapKeyRef: + name: {{ include "n8n.fullname" . }} + key: WEBHOOK_URL + - name: GENERIC_TIMEZONE + valueFrom: + configMapKeyRef: + name: {{ include "n8n.fullname" . }} + key: GENERIC_TIMEZONE + - name: N8N_SECURE_COOKIE + valueFrom: + configMapKeyRef: + name: {{ include "n8n.fullname" . }} + key: N8N_SECURE_COOKIE + - name: DB_TYPE + valueFrom: + configMapKeyRef: + name: {{ include "n8n.fullname" . }} + key: DB_TYPE + - name: DB_SQLITE_FILE + valueFrom: + configMapKeyRef: + name: {{ include "n8n.fullname" . }} + key: DB_SQLITE_FILE + # Sensitive values from Secret + - name: N8N_ENCRYPTION_KEY + valueFrom: + secretKeyRef: + name: {{ .Values.existingSecret | default (include "n8n.fullname" .) }} + key: N8N_ENCRYPTION_KEY + {{- if .Values.env }} + {{- range $key, $value := .Values.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .Values.envFrom }} + envFrom: + {{- range $envFrom := .Values.envFrom }} + {{- if $envFrom.configMapRef }} + - configMapRef: + name: {{ $envFrom.configMapRef.name }} + {{- end }} + {{- if $envFrom.secretRef }} + - secretRef: + name: {{ $envFrom.secretRef.name }} + {{- end }} + {{- end }} + {{- end }} + livenessProbe: + httpGet: + path: /healthz + port: http + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /healthz + port: http + initialDelaySeconds: 10 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 3 + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: data + mountPath: /root/.n8n + volumes: + - name: data + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ include "n8n.fullname" . }} + {{- else }} + emptyDir: {} + {{- end }} diff --git a/charts/n8n/templates/ingress.yaml b/charts/n8n/templates/ingress.yaml new file mode 100644 index 0000000..31537a8 --- /dev/null +++ b/charts/n8n/templates/ingress.yaml @@ -0,0 +1,45 @@ +{{- if .Values.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "n8n.fullname" . }} + labels: + {{- include "n8n.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + {{- if .secretName }} + secretName: {{ .secretName | quote }} + {{- end }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if .pathType }} + pathType: {{ .pathType }} + {{- end }} + backend: + service: + name: {{ include "n8n.fullname" $ }} + port: + number: {{ $.Values.service.port | default 80 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/n8n/templates/pvc.yaml b/charts/n8n/templates/pvc.yaml new file mode 100644 index 0000000..486f36d --- /dev/null +++ b/charts/n8n/templates/pvc.yaml @@ -0,0 +1,15 @@ +{{- if .Values.persistence.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "n8n.fullname" . }} + labels: + {{- include "n8n.labels" . | nindent 4 }} +spec: + accessModes: + - ReadWriteOnce + storageClassName: {{ .Values.persistence.storageClass }} + resources: + requests: + storage: {{ .Values.persistence.size | default "10Gi" }} +{{- end }} diff --git a/charts/n8n/templates/service.yaml b/charts/n8n/templates/service.yaml new file mode 100644 index 0000000..5ad32e9 --- /dev/null +++ b/charts/n8n/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "n8n.fullname" . }} + labels: + {{- include "n8n.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type | default "ClusterIP" }} + ports: + - port: {{ .Values.service.port | default 80 }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "n8n.selectorLabels" . | nindent 4 }} diff --git a/charts/n8n/values.yaml b/charts/n8n/values.yaml new file mode 100644 index 0000000..c4ca372 --- /dev/null +++ b/charts/n8n/values.yaml @@ -0,0 +1,74 @@ +# Default values for n8n +replicaCount: 1 + +image: + repository: n8n + tag: latest + pullPolicy: IfNotPresent + +nameOverride: "" +fullnameOverride: "" + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: true + className: traefik + annotations: {} + # cert-manager.io/cluster-issuer: letsencrypt + # traefik.ingress.kubernetes.io/router.entrypoints: web + hosts: + - host: n8n.example.com + paths: + - path: / + pathType: Prefix + tls: [] + # - secretName: n8n-cert + # hosts: + # - n8n.example.com + +persistence: + enabled: true + storageClass: nfs-client + size: 10Gi + +# Configuration values for n8n +config: + N8N_HOST: n8n.example.com + N8N_PROTOCOL: https + WEBHOOK_URL: https://n8n.example.com + GENERIC_TIMEZONE: Asia/Jerusalem + N8N_SECURE_COOKIE: "true" + DB_TYPE: sqlite + DB_SQLITE_FILE: /root/.n8n/database.db + +# Extra configuration data to be added to ConfigMap +configData: {} + +# Extra environment variables +env: {} + # LOG_LEVEL: info + +# Environment variables from ConfigMaps or Secrets +envFrom: [] + # - configMapRef: + # name: n8n-extra-config + # - secretRef: + # name: n8n-tokens + +# Reference to an existing Secret for sensitive values +# If not provided, Secret with the same name as the release will be used +existingSecret: "" + +resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + +nodeSelector: {} + # workload: general diff --git a/manifests/n8n/values.yaml b/manifests/n8n/values.yaml new file mode 100644 index 0000000..3e999a7 --- /dev/null +++ b/manifests/n8n/values.yaml @@ -0,0 +1,49 @@ +# N8N Manifest Values +# This file overrides chart defaults for the dev-tools namespace deployment + +image: + repository: n8n + tag: latest + pullPolicy: IfNotPresent + +nodeSelector: + workload: general + +config: + N8N_HOST: n8n.dvirlabs.com + N8N_PROTOCOL: https + WEBHOOK_URL: https://n8n.dvirlabs.com + GENERIC_TIMEZONE: Asia/Jerusalem + N8N_SECURE_COOKIE: "true" + DB_TYPE: sqlite + DB_SQLITE_FILE: /root/.n8n/database.db + +ingress: + enabled: true + className: traefik + annotations: + cert-manager.io/cluster-issuer: letsencrypt + traefik.ingress.kubernetes.io/router.entrypoints: web + hosts: + - host: n8n.dvirlabs.com + paths: + - path: / + pathType: Prefix + tls: [] + +persistence: + enabled: true + storageClass: nfs-client + size: 10Gi + +# Reference to existing Secret for sensitive values like N8N_ENCRYPTION_KEY +# This Secret must be created in the dev-tools namespace before ArgoCD syncs +existingSecret: n8n-secrets + +resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi