# Deploy n8n on K8s with 8gears chart

> For the complete documentation index, see [llms.txt](https://iqbalaissaoui.com/llms.txt).

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

```HCL
#######################################
#  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.

> **Tip:**
> References
>
>
>
> [Self-contained Terraform file used in this post](https://gitlab.com/iaissaoui/examples/-/blob/main/deployments/n8n.tf)

