Deploy n8n on K8s with 8gears chart
This is a quick code share of how to deploy a stateless n8n instance on the OCI cluster we created in the previous articles using the 8gears chart.
You can apply this configuration with Terraform:
Snippet
#######################################
# n8n.tf – bootstrap n8n
#######################################
############################
# (1) Namespace
############################
resource "kubernetes_namespace" "n8n" {
metadata {
name = var.n8n_namespace
}
}
############################
# (2) One Secret for the
# really sensitive stuff
############################
resource "kubernetes_secret" "n8n_sensitive" {
metadata {
name = var.n8n_secret_name # e.g. "n8n-secret"
namespace = kubernetes_namespace.n8n.metadata[0].name
}
data = {
encryption_key = base64encode(var.n8n_encryption_key) # >32-byte random hex
}
type = "Opaque"
}
############################
# (3) Helm release
############################
resource "helm_release" "n8n" {
name = "n8n"
repository = "oci://8gears.container-registry.com/library"
chart = "n8n"
version = var.n8n_chart_version # default = "1.0.10"
namespace = kubernetes_namespace.n8n.metadata[0].name
# Merge order: chart defaults ← this YAML ← any --set (none here)
values = [<<-YAML
#
# 1️⃣ Ingress: host + /n8n sub-path
#
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/rewrite-target: /
hosts:
- host: ${var.n8n_domain}
paths:
- /
tls:
- secretName: n8n-tls
hosts:
- ${var.n8n_domain}
#
# 2️⃣ n8n runtime configuration
#
image:
repository: n8nio/n8n
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: "latest"
main:
config:
n8n: {}
secret: {}
extraEnv:
- name: N8N_LOG_LEVEL
value: debug
- name: N8N_ENCRYPTION_KEY
valueFrom:
secretKeyRef:
name: ${kubernetes_secret.n8n_sensitive.metadata[0].name}
key: encryption_key
#
# 3️⃣ Redis/Valkey disabled (enable if you add workers)
#
valkey:
enabled: false
YAML
]
# Deploy only after namespace & secret exist
depends_on = [
kubernetes_secret.n8n_sensitive
]
}
############################
# (4) Inputs with safe defaults
############################
variable "n8n_namespace" {
type = string
default = "n8n"
}
variable "n8n_chart_version" {
type = string
default = "1.0.10"
}
variable "n8n_domain" {
type = string
default = "n8n.example.com" # Public FQDN of your n8n instance
}
variable "n8n_secret_name" {
type = string
default = "n8n-secret"
}
variable "n8n_encryption_key" {
type = string
sensitive = true
}
Source Code
You can explore all the material shown in this post in the public repository.
13 July 2025