Skip to content

n8n

Deploy n8n on Kubernetes — a workflow automation platform with a visual editor, 200+ integrations, and code nodes. Supports SQLite (zero-configuration default), and PostgreSQL, with Redis-backed queue mode for horizontal scaling of workflow executions.

encryptionKey protects all stored credentials — losing it invalidates every workflow connection

n8n.encryptionKey encrypts OAuth tokens, API keys, and passwords stored in workflow credentials. If the key changes (including during reinstall with a new auto-generated key), all saved credentials in all workflows become permanently unreadable. Always persist it via encryptionKey.existingSecret and never rotate it in production.

Key Features

  • Two database backends — SQLite (default) and PostgreSQL
  • Queue mode — Redis-backed horizontal scaling with separate worker Deployments
  • Encryption key protection — all workflow credentials encrypted at rest
  • Webhook URL required — must match the external-facing URL for triggers to work
  • Database-aware backuptar for SQLite, pg_dump for PostgreSQL

Installation

HTTPS repository:

helm repo add helmforge https://repo.helmforge.dev
helm repo update
helm install n8n helmforge/n8n -f values.yaml

OCI registry:

helm install n8n oci://ghcr.io/helmforgedev/helm/n8n -f values.yaml

Deployment Examples

# values.yaml — n8n with SQLite (zero database configuration)
n8n:
  webhookUrl: 'https://n8n.example.com' # required for webhook triggers

encryptionKey:
  existingSecret: n8n-master-secret # key: encryption-key (never rotate)
  existingSecretKey: encryption-key

persistence:
  enabled: true
  size: 10Gi # SQLite DB + installed custom nodes

ingress:
  enabled: true
  ingressClassName: traefik
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: n8n.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: n8n-tls
      hosts:
        - n8n.example.com
# values.yaml — n8n with bundled PostgreSQL
n8n:
  webhookUrl: 'https://n8n.example.com'
  logLevel: info

encryptionKey:
  existingSecret: n8n-master-secret

postgresql:
  enabled: true
  auth:
    database: n8n
    username: n8n
    password: 'strong-db-password'
  primary:
    persistence:
      enabled: true
      size: 20Gi

persistence:
  enabled: true
  size: 5Gi # custom nodes (no SQLite when PostgreSQL is active)

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: n8n.example.com
      paths:
        - path: /
          pathType: Prefix
# values.yaml — n8n in queue mode with 3 workers
# Queue mode separates the main pod (editor + triggers) from worker pods (executions)
n8n:
  webhookUrl: 'https://n8n.example.com'

encryptionKey:
  existingSecret: n8n-master-secret

postgresql:
  enabled: true
  auth:
    password: 'strong-db-password'

redis:
  enabled: true
  auth:
    password: 'strong-redis-password'

queue:
  enabled: true
  workers: 3 # creates 3 separate worker Deployment pods
  concurrency: 10 # workflows executed simultaneously per worker

persistence:
  enabled: true
  size: 5Gi

ingress:
  enabled: true
  ingressClassName: traefik
  hosts:
    - host: n8n.example.com
      paths:
        - path: /
          pathType: Prefix
# values.yaml — n8n with external PostgreSQL and daily backup
n8n:
  webhookUrl: 'https://n8n.example.com'

encryptionKey:
  existingSecret: n8n-master-secret

postgresql:
  enabled: false

database:
  mode: external
  external:
    vendor: postgres
    host: postgres.database.svc.cluster.local
    name: n8n
    username: n8n
    existingSecret: n8n-db-credentials
    existingSecretPasswordKey: database-password

persistence:
  enabled: true
  size: 5Gi

backup:
  enabled: true
  schedule: '0 3 * * *'
  s3:
    endpoint: https://s3.amazonaws.com
    bucket: n8n-backups
    existingSecret: n8n-s3-credentials

Configuration Reference

Core

Parameter Type Default Description
nameOverride string "" Override the chart name.
fullnameOverride string "" Override the full release name.
commonLabels object {} Extra labels added to all resources.

Image

Parameter Type Default Description
image.repository string docker.io/n8nio/n8n n8n container image.
image.tag string "2.38.4" Image tag.
image.pullPolicy string IfNotPresent Image pull policy.

Task Runners

Parameter Type Default Description
taskRunners.mode string external Run the dedicated task-runner sidecar.
taskRunners.image.repository string docker.io/n8nio/runners External task-runner image repository.
taskRunners.image.tag string "" Runner tag; empty inherits image.tag (2.38.4).
taskRunners.image.pullPolicy string IfNotPresent External task-runner image pull policy.

n8n Configuration

Parameter Type Default Description
n8n.encryptionKey string "" Credential encryption key. Auto-generated if empty. Use existingSecret.
n8n.webhookUrl string "" Full external URL for webhook triggers. Required for all webhook nodes.
n8n.editorBaseUrl string "" Editor base URL. Auto-detected from Ingress if empty.
n8n.logLevel string info Log level: silent, error, warn, info, debug, verbose.
n8n.logOutput string console Log output destination: console or file.
n8n.extraEnv array [] Extra environment variables (e.g. GENERIC_TIMEZONE, N8N_DIAGNOSTICS_ENABLED).

Encryption Key

Parameter Type Default Description
encryptionKey.existingSecret string "" Existing secret containing the encryption key.
encryptionKey.existingSecretKey string encryption-key Key for the encryption key in the existing secret.

Queue Mode

Parameter Type Default Description
queue.enabled boolean false Enable Redis-backed queue mode (main pod + separate worker Deployments).
queue.workers integer 1 Number of worker replica Deployments.
queue.concurrency integer 10 Simultaneous workflow executions per worker.
queue.resources object {} CPU and memory requests/limits for worker pods.
queue.external.host string "" External Redis host (alternative to subchart).
queue.external.existingSecret string "" Existing secret for external Redis password.

Database

Auto-detection precedence (database.mode: auto):

Priority Condition Result
1 database.external.host or external.existingSecret External DB
2 postgresql.enabled: true PostgreSQL subchart
3 None of the above SQLite (default)
Parameter Type Default Description
database.mode string auto Database mode: auto, sqlite, external, postgresql.
database.sqlite.file string /home/node/.n8n/database.sqlite SQLite file path inside the data volume.
database.external.vendor string postgres External DB vendor: postgres only.
database.external.host string "" External database hostname.
database.external.existingSecret string "" Existing secret with database password.
database.external.existingSecretPasswordKey string database-password Key for the password.

Subcharts

Parameter Type Default Description
postgresql.enabled boolean false Deploy the bundled PostgreSQL subchart.
postgresql.auth.password string "" Password. Auto-generated if empty.
postgresql.primary.persistence.size string 8Gi PVC size for PostgreSQL.
redis.enabled boolean false Deploy the bundled Redis subchart.
redis.primary.persistence.size string 1Gi PVC size for Redis.

Persistence

Parameter Type Default Description
persistence.enabled boolean true Enable PVC for /home/node/.n8n (SQLite DB + custom nodes).
persistence.size string 5Gi PVC size.
persistence.storageClass string "" StorageClass for the PVC.
persistence.existingClaim string "" Use an existing PVC.

Backup

Backup mode is automatically selected based on the active database vendor.

Parameter Type Default Description
backup.enabled boolean false Enable scheduled S3 backup CronJob.
backup.schedule string "0 3 * * *" Cron schedule.
backup.archivePrefix string n8n Prefix for backup archive filenames.
backup.s3.endpoint string "" S3-compatible endpoint URL.
backup.s3.bucket string "" Target bucket name.
backup.s3.existingSecret string "" Existing secret with S3 credentials.
backup.database.postgresDumpArgs string "" Extra arguments for pg_dump.

Service, Ingress, Probes

Parameter Type Default Description
service.type string ClusterIP Service type.
ingress.enabled boolean false Enable an Ingress resource.
ingress.ingressClassName string "" Ingress class name.
startupProbe.enabled boolean true Startup probe on /healthz.
livenessProbe.enabled boolean true Liveness probe on /healthz.
readinessProbe.enabled boolean true Readiness probe on /healthz.
resources object {} CPU and memory requests/limits.
extraManifests array [] Extra Kubernetes manifests.

Upgrade Notes

n8n 2.38.4 includes the 2.36–2.38 runner broker and shutdown fixes, database pool recovery, encryption-key seeding and queue execution fixes. Back up the database and data volume, preserve the encryption key, and validate workflows and credentials in staging before upgrading. Keep the app and external runner tags aligned; an empty taskRunners.image.tag inherits image.tag.

Use helm upgrade --reset-then-reuse-values with image.tag=2.38.4 and update any separately pinned runner tag. Existing generated encryption keys and runner tokens are retained through Helm lookup; use existing Secrets for offline rendering or GitOps. Automatic database migrations require a recoverable backup.

SQLite updates now use Recreate to stop the old main process before the new version opens the same database. Plan for brief downtime. The Python toggle taskRunners.nativePython.enabled now controls the n8n 2.x variable N8N_PYTHON_ENABLED; it remains disabled by default and requires external runners.

MySQL and MariaDB storage migration

n8n removed MySQL/MariaDB storage in version 2.0. Earlier chart releases still exposed these unsupported options. This chart now rejects mysql.enabled=true, database.mode=mysql and non-PostgreSQL external vendors, and no longer bundles MySQL or MySQL backup jobs. The MySQL workflow node is unaffected.

If an older deployment uses MySQL/MariaDB, stop here and migrate its data using the upstream migration procedure on a compatible source release. Back up the database and encryption key, migrate into a separate PostgreSQL instance, and verify credentials, workflows and executions before switching traffic. Changing database.mode alone does not migrate data. Do not apply this release over an existing bundled MySQL installation until its data has been migrated and its backup and PVC recovery have been verified.

See the 2.0 storage migration guidance and upstream releases.

More Information