n8n-helm

n8n Helm Chart

This directory contains the Helm chart for deploying n8n, an extendable workflow automation tool. Refer to the changelog for release notes.

Quick start

Add the chart repository and install the release:

helm repo add n8n https://anyfavors.github.io/n8n-helm
helm repo update

# install the chart with the default values
helm install my-n8n n8n/n8n

Customise the deployment by supplying your own values.yaml or overriding settings on the command line.

Common configuration options

See values.yaml for all available settings.

Security

By default the chart runs the n8n container as a non-root user and mounts the root filesystem as read-only with privilege escalation disabled. These settings are defined in podSecurityContext and securityContext in values.yaml and can be adjusted if needed.

Automatic mounting of the ServiceAccount token is disabled via serviceAccount.automount to limit access to the Kubernetes API and reduce the attack surface.

Updating n8n versions

When a new n8n release is published, bump the appVersion field in Chart.yaml and update the default image.tag in values.yaml to match.

CPU and memory settings

The chart ships with minimal resource requests and limits suitable for test deployments. For production workloads increase the values under the resources block in your values.yaml file or via command line flags. For example:

helm install my-n8n n8n/n8n \
  --set resources.requests.cpu=500m \
  --set resources.requests.memory=512Mi \
  --set resources.limits.cpu=1 \
  --set resources.limits.memory=1Gi

Webhook URL example

Specify an external URL for webhook callbacks using webhookUrl:

webhookUrl: https://my-n8n.example.com/

Extra containers example

Additional sidecars can be defined via extraContainers:

extraContainers:
  - name: sidecar
    image: busybox
    command: ["sh", "-c", "echo sidecar"]

Publishing

Chart packages are created automatically using chart-releaser when commits land on main. Before the first release, create a gh-pages branch in the repository and configure GitHub Pages to serve from it (the branch can start with an empty index.yaml). To cut a release, bump the version in Chart.yaml and push the change. The release.yaml workflow will upload the packaged chart to GitHub and update the index on gh-pages. Users can then add https://anyfavors.github.io/n8n-helm as a Helm repository to install published versions.

Values

Key Type Default Description
affinity object {}  
autoscaling.enabled bool false  
autoscaling.maxReplicas int 100  
autoscaling.minReplicas int 1  
autoscaling.targetCPUUtilizationPercentage int 80  
database.database string ""  
database.host string ""  
database.password string ""  
database.passwordSecret.key string "password"  
database.passwordSecret.name string ""  
database.port int 5432  
database.user string ""  
encryptionKeySecret.key string "encryptionKey"  
encryptionKeySecret.name string ""  
extraConfigMaps list []  
extraContainers list []  
extraEnv list []  
extraSecrets list []  
fullnameOverride string ""  
image.pullPolicy string "IfNotPresent"  
image.repository string "n8nio/n8n"  
image.tag string ""  
imagePullSecrets list []  
ingress.annotations object {}  
ingress.className string ""  
ingress.enabled bool false  
ingress.hosts[0].host string "chart-example.local"  
ingress.hosts[0].paths[0].path string "/"  
ingress.hosts[0].paths[0].pathType string "ImplementationSpecific"  
ingress.tls list []  
initContainers list []  
lifecycle object {}  
livenessProbe.httpGet.path string "/"  
livenessProbe.httpGet.port string "http"  
nameOverride string ""  
networkPolicy.egress list []  
networkPolicy.enabled bool false  
networkPolicy.ingress list []  
networkPolicy.policyTypes[0] string "Ingress"  
networkPolicy.policyTypes[1] string "Egress"  
nodeSelector object {}  
pdb.enabled bool false  
persistence.enabled bool false  
persistence.existingClaim string ""  
persistence.size string "8Gi"  
persistence.storageClass string ""  
podAnnotations object {}  
podLabels object {}  
podSecurityContext.fsGroup int 1000  
podSecurityContext.runAsUser int 1000  
podSecurityContext.seccompProfile.type string "RuntimeDefault"  
rbac.create bool false  
readinessProbe.httpGet.path string "/"  
readinessProbe.httpGet.port string "http"  
replicaCount int 1  
resources.limits.cpu string "250m"  
resources.limits.memory string "512Mi"  
resources.requests.cpu string "100m"  
resources.requests.memory string "256Mi"  
securityContext.allowPrivilegeEscalation bool false  
securityContext.capabilities.drop[0] string "ALL"  
securityContext.readOnlyRootFilesystem bool true  
securityContext.runAsNonRoot bool true  
service.annotations object {}  
service.port int 5678  
service.type string "ClusterIP"  
serviceAccount.annotations object {}  
serviceAccount.automount bool false  
serviceAccount.create bool true  
serviceAccount.name string ""  
strategy.maxSurge string "25%"  
strategy.maxUnavailable string "25%"  
strategy.type string "RollingUpdate"  
tolerations list []  
volumeMounts list []  
volumes list []  
webhookUrl string ""  

Autogenerated from chart metadata using helm-docs v1.14.2