[!NOTE] The n8n Helm chart is growing in popularity. We're looking for additional conscientious and accurate maintainers and contributors to improve and maintain this chart, governance, development, documentation and CI/CD workflows. If you're interested in making a difference, join the discussion.
n8n Helm Chart for Kubernetes
n8n is an extendable workflow automation tool.
The Helm chart source code location is github.com/8gears/n8n-helm-chart
Requirements
Before you start, make sure you have the following tools ready:
- Helm >= 3.8
- external Postgres DB or embedded SQLite (SQLite is bundled with n8n)
- Helmfile (Optional)
Overview
The values.yaml file is divided into multiple sections (global, n8n, and Kubernetes).
Use this structure to orient yourself.
- Global and chart wide values, like the image repository, image tag, etc.
- Ingress, (default is nginx, but you can change it to your own ingress controller)
- Main n8n app configuration + Kubernetes specific settings
- Worker related settings + Kubernetes specific settings
- Webhook related settings + Kubernetes specific settings
- Sandbox, the isolated execution environment the instance-ai module needs
- Raw Resources to pass through your own manifests like GatewayAPI, ServiceMonitor etc.
- Valkey/Redis related settings + Kubernetes specific settings
Configurating N8n via Values and Environment Variables
These n8n configuration should be added to main.config: or main.secret: in the values.yaml file.
See the example section and other example in the /examples directory of this repo.
[!IMPORTANT] The YAML nodes
configandsecretin the values.yaml are transformed 1:1 into K8s ENV variables.
main:
config:
n8n:
encryption_key: "my_secret" # ==> turns into ENV: N8N_ENCRYPTION_KEY=my_secret
db:
type: postgresdb # ==> turns into ENV: DB_TYPE=postgresdb
postgresdb:
host: 192.168.0.52 # ==> turns into ENV: DB_POSTGRESDB_HOST=192.168.0.52
node:
function_allow_builtin: "*" # ==> turns into ENV: NODE_FUNCTION_ALLOW_BUILTIN="*"
Consult the n8n Environment Variables Documentation
You decide what should go into secret and what should be a config.
There is no restriction, mix and match as you like.
Installation
Install chart
helm install my-n8n oci://8gears.container-registry.com/library/n8n --version 1.0.0
Examples
A typical example of a config in combination with a secret.
You can find various other examples in the examples directory of this repository.
#small deployment with nodeport for local testing or small deployments
main:
config:
n8n:
hide_usage_page: true
secret:
n8n:
encryption_key: "<your-secure-encryption-key>"
resources:
limits:
memory: 2048Mi
requests:
memory: 512Mi
service:
type: NodePort
port: 5678
Values File
Global Section
image:
repository: n8nio/n8n
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
imagePullSecrets: []
# The Name to use for the chart. Will be the prefix of all resources aka. The Chart.Name (default is 'n8n')
nameOverride:
# Override the full name of the deployment. When empty, the name will be "{release-name}-{chart-name}" or the value of nameOverride if specified
fullnameOverride:
# Add entries to a pod's /etc/hosts file, mapping custom IP addresses to hostnames.
hostAliases: []
#- ip: 8.8.8.8
# hostnames:
# - service-example.local
#
# Ingress
#
ingress:
enabled: false
annotations: {}
# define a custom ingress class Name, like "traefik" or "nginx"
className: ""
hosts:
- host: workflow.example.com
paths:
- path: /
pathType: Prefix
tls:
- hosts:
- workflow.example.com
secretName: host-domain-cert
# ... next n8n specific section
N8N Specific Config Section in Values File
Every possible n8n config value can be set, even if it is not mentioned in the excerpt below. Treat the n8n provided configuration documentation as the source of truth, this Charts just forwards everything down to the n8n pods.
## ... after global section
## the main (n8n) application related configuration + Kubernetes specific settings
## The config: {} dictionary is converted to environmental variables in the ConfigMap.
main:
# See https://docs.n8n.io/hosting/configuration/environment-variables/ for all values.
config: {}
# n8n:
# db:
# type: postgresdb
# postgresdb:
# host: 192.168.0.52
# Dictionary for secrets, unlike config:, the values here will end up in the secret file.
# The YAML entry db.postgresdb.password: my_secret is transformed DB_POSTGRESDB_password=bXlfc2VjcmV0
# See https://docs.n8n.io/hosting/configuration/environment-variables/
secret: {}
# n8n:
# if you run n8n stateless, you should provide an encryption key here.
# encryption_key:
#
# db:
# postgresdb:
# password: 'big secret'
# Extra environmental variables, so you can reference other configmaps and secrets into n8n as env vars.
extraEnv:
# N8N_DB_POSTGRESDB_NAME:
# valueFrom:
# secretKeyRef:
# name: db-app
# key: dbname
# ... next k8s specific values section
Kubernetes Specific Values Section
this section of the yaml file contains the typical Kubernetes specific setting
related to the application deployment and operation but not the application itself.
# ... after n8n specific section
#
persistence:
# If true, use a Persistent Volume Claim, If false, use emptyDir
enabled: false
# what type volume, possible options are [existing, emptyDir, dynamic] dynamic for Dynamic Volume Provisioning, existing for using an existing Claim
type: emptyDir
# Persistent Volume Storage Class
# If defined, storageClassName:
# If set to "-", storageClassName: "", which disables dynamic provisioning
# If undefined (the default) or set to null, no storageClassName spec is
# set, choosing the default provisioner. (gp2 on AWS, standard on
# GKE, AWS & OpenStack)
#
# storageClass: "-"
# PVC annotations
#
# If you need this annotation include it under `values.yml` file and pvc.yml template will add it.
# This is not maintained at Helm v3 anymore.
# https://github.com/8gears/n8n-helm-chart/issues/8
#
# annotations:
# helm.sh/resource-policy: keep
# Persistent Volume Access Mode
#
accessModes:
- ReadWriteOnce
# Persistent Volume size
size: 1Gi
# Use an existing PVC
# existingClaim:
extraVolumes: []
# - name: db-ca-cert
# secret:
# secretName: db-ca
# items:
# - key: ca.crt
# path: ca.crt
extraVolumeMounts: []
# - name: db-ca-cert
# mountPath: /etc/ssl/certs/postgresql
# readOnly: true
# Number of desired pods. More than one pod is supported in n8n enterprise.
replicaCount: 1
# here you can specify the deployment strategy as Recreate or RollingUpdate with optional maxSurge and maxUnavailable
# If these options are not set, default values are 25%
# deploymentStrategy:
# type: Recreate | RollingUpdate
# maxSurge: "50%"
# maxUnavailable: "50%"
deploymentStrategy:
type: "Recreate"
# maxSurge: "50%"
# maxUnavailable: "50%"
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
# Annotations to be implemented on the main service deployment
deploymentAnnotations: {}
# Labels to be implemented on the main service deployment
deploymentLabels: {}
# Annotations to be implemented on the main service pod
podAnnotations: {}
# Labels to be implemented on the main service pod
podLabels: {}
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
# here you can specify lifecycle hooks - it can be used e.g., to easily add packages to the container without building
# your own docker image
# see https://github.com/8gears/n8n-helm-chart/pull/30