{"id":46099615,"url":"https://github.com/idirouhab/n8n-helm-chart","last_synced_at":"2026-03-01T19:32:17.038Z","repository":{"id":319380456,"uuid":"1054558242","full_name":"idirouhab/n8n-helm-chart","owner":"idirouhab","description":"Helm chart for n8n","archived":false,"fork":false,"pushed_at":"2025-11-13T14:35:46.000Z","size":173,"stargazers_count":9,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-13T16:29:28.129Z","etag":null,"topics":["automation","devops","helm","helm-chart","kubernetes","monitoring","n8n","postgresql","prometheus","queue","redis","scaling","workflow-automation"],"latest_commit_sha":null,"homepage":null,"language":"Smarty","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/idirouhab.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-11T02:42:57.000Z","updated_at":"2025-11-13T14:35:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"0a2cf356-56c3-44d4-9da7-7f23a96a6386","html_url":"https://github.com/idirouhab/n8n-helm-chart","commit_stats":null,"previous_names":["idirouhab/n8n-helm-chart"],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/idirouhab/n8n-helm-chart","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idirouhab%2Fn8n-helm-chart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idirouhab%2Fn8n-helm-chart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idirouhab%2Fn8n-helm-chart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idirouhab%2Fn8n-helm-chart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/idirouhab","download_url":"https://codeload.github.com/idirouhab/n8n-helm-chart/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/idirouhab%2Fn8n-helm-chart/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29981413,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T16:35:47.903Z","status":"ssl_error","status_checked_at":"2026-03-01T16:35:44.899Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","devops","helm","helm-chart","kubernetes","monitoring","n8n","postgresql","prometheus","queue","redis","scaling","workflow-automation"],"created_at":"2026-03-01T19:32:16.378Z","updated_at":"2026-03-01T19:32:17.020Z","avatar_url":"https://github.com/idirouhab.png","language":"Smarty","funding_links":[],"categories":[],"sub_categories":[],"readme":"# n8n Helm Chart\n\n\u003e ⚠️ This is a **community-maintained** Helm chart and is not officially supported by the n8n team.\n\n## Installation\n\n### Option 1: OCI Registry (Recommended)\n\n```bash\n# Create required secrets\nkubectl create secret generic n8n-db-password --from-literal=password=\"your-db-password\"\nkubectl create secret generic n8n-core-secrets \\\n  --from-literal=N8N_ENCRYPTION_KEY=\"$(openssl rand -base64 32)\" \\\n  --from-literal=N8N_HOST=\"n8n.example.com\" \\\n  --from-literal=N8N_PORT=\"5678\" \\\n  --from-literal=N8N_PROTOCOL=\"https\"\n\n# Install the chart from OCI registry\nhelm install n8n oci://registry-1.docker.io/idirouhab/n8n \\\n  --set database.host=postgres.example.com \\\n  --set database.passwordSecret.name=n8n-db-password \\\n  --set redis.host=redis.example.com \\\n  --set secretRefs.existingSecret=n8n-core-secrets \\\n  --set ingress.enabled=true \\\n  --set ingress.hosts[0].host=n8n.example.com\n```\n\n### Option 2: Development (Git Repository)\n\n```bash\n# Clone for development or customization\ngit clone https://github.com/idirouhab/n8n-helm-chart.git\ncd n8n-helm-chart\n\n# 1. Create required secrets\n./examples/create-secrets.sh\n\n# 2. Choose and customize an example\ncp examples/production-aws.yaml my-values.yaml\n\n# 3. Deploy\nhelm install n8n ./charts/n8n -f my-values.yaml\n```\n\n[See all available examples](./examples/)\n\n## Overview\n\nThis Helm chart deploys [n8n](https://n8n.io), a workflow automation platform, on Kubernetes.\n\n### Deployment Modes\n\nThis chart **only supports queue mode** with external PostgreSQL and Redis dependencies for better scalability and production readiness.\n\n| Mode | Description | When to Choose |\n|------|-------------|----------------|\n| **Queue Mode** | Separate main (web/API) and worker pods | Default mode - suitable for all workloads, provides scalability and resilience |\n| **Multi-Main Queue Mode** | Multiple main pods + multiple workers | High-availability production setups with large webhook/API traffic and multiple concurrent editors/users |\n| **Webhook Processor Mode** | Dedicated webhook processing pods + main + workers | Ultra high-throughput webhook scenarios requiring massive parallel webhook processing |\n\nNote: This chart enforces external PostgreSQL and Redis for all deployments to ensure production-ready configurations.\n\n## Prerequisites\n\n### Required\n- Kubernetes cluster v1.25+\n- Helm 3.x\n- PostgreSQL database (external, required)\n- Redis instance (external, required)\n- Kubernetes secrets (see [Secrets Management](#secrets-management))\n\n### Optional\n- Ingress controller (for external access)\n- Cert-manager (for TLS)\n\n## Webhook Processors Important Notice\n\nIf using webhook processors with `disableProductionWebhooksOnMainProcess: true`, you **MUST** configure your load balancer/ingress to route traffic correctly:\n\n```\n/webhook/*      → webhook processor service (production webhooks)\n/webhook-test/* → main service             (test webhooks)\n/*              → main service             (UI, API, everything else)\n```\n\n**Without proper routing, production webhooks will fail!** See [`examples/webhook-processors-guide.md`](./examples/webhook-processors-guide.md) for complete setup instructions.\n\n## Secrets Management\n\nThe chart requires two secrets to be created before installation:\n\n### Required Secrets\n\n**Database Password**:\n```bash\nkubectl create secret generic n8n-db-password \\\n  --from-literal=password=\"your-postgres-password\"\n```\n\n**n8n Configuration**:\n```bash\nkubectl create secret generic n8n-core-secrets \\\n  --from-literal=N8N_ENCRYPTION_KEY=\"$(openssl rand -base64 32)\" \\\n  --from-literal=N8N_HOST=\"n8n.example.com\" \\\n  --from-literal=N8N_PORT=\"5678\" \\\n  --from-literal=N8N_PROTOCOL=\"https\"\n```\n\n### Quick Setup Script\n\nUse the provided script to create all required secrets:\n\n```bash\n# Edit the script with your values\nnano examples/create-secrets.sh\n\n# Run it\n./examples/create-secrets.sh\n```\n\n\u003e **Important**: Save the generated `N8N_ENCRYPTION_KEY` securely - you'll need it for backups!\n\n## Quick Start\n\n## Detailed Installation Guide\n\n### 1. Check Available Versions\n\n```bash\n# List available chart versions from Docker Hub\nhelm show chart oci://registry-1.docker.io/idirouhab/n8n\n```\n\n### 2. Create Required Secrets\n\n**Before installing the chart**, create the required secrets:\n\n```bash\n# Method 1: Use the provided script (clone repo first)\ngit clone https://github.com/idirouhab/n8n-helm-chart.git\ncd n8n-helm-chart\n./examples/create-secrets.sh\n\n# Method 2: Create manually\nkubectl create secret generic n8n-db-password --from-literal=password=\"your-db-password\"\nkubectl create secret generic n8n-core-secrets \\\n  --from-literal=N8N_ENCRYPTION_KEY=\"$(openssl rand -base64 32)\" \\\n  --from-literal=N8N_HOST=\"n8n.example.com\" \\\n  --from-literal=N8N_PORT=\"5678\" \\\n  --from-literal=N8N_PROTOCOL=\"https\"\n```\n\n### 3. Install from OCI Registry\n\n#### Basic Queue Mode (Default)\n\n```bash\nhelm install n8n oci://registry-1.docker.io/idirouhab/n8n \\\n  --set database.host=postgres.example.com \\\n  --set database.passwordSecret.name=n8n-db-password \\\n  --set redis.host=redis.example.com \\\n  --set secretRefs.existingSecret=n8n-core-secrets \\\n  --set ingress.enabled=true \\\n  --set ingress.hosts[0].host=n8n.example.com\n```\n\n#### AWS ElastiCache Configuration\n\n```bash\n# For AWS ElastiCache (TLS required)\nhelm install n8n oci://registry-1.docker.io/idirouhab/n8n \\\n  --set database.host=postgres.example.com \\\n  --set database.passwordSecret.name=n8n-db-password \\\n  --set redis.host=master.your-cluster.cache.amazonaws.com \\\n  --set redis.tls=true \\\n  --set secretRefs.existingSecret=n8n-core-secrets \\\n  --set ingress.enabled=true \\\n  --set ingress.hosts[0].host=n8n.example.com\n```\n\n#### Specific Version Installation\n\n```bash\n# Install a specific version\nhelm install n8n oci://registry-1.docker.io/idirouhab/n8n --version 0.9.2\n```\n\n#### Custom Namespace Installation\n\n```bash\n# Create secrets in custom namespace\nkubectl create namespace n8n-production\nkubectl create secret generic n8n-db-password --namespace n8n-production --from-literal=password=\"your-db-password\"\nkubectl create secret generic n8n-core-secrets --namespace n8n-production \\\n  --from-literal=N8N_ENCRYPTION_KEY=\"$(openssl rand -base64 32)\" \\\n  --from-literal=N8N_HOST=\"n8n.example.com\" \\\n  --from-literal=N8N_PORT=\"5678\" \\\n  --from-literal=N8N_PROTOCOL=\"https\"\n\n# Install in custom namespace\nhelm install n8n oci://registry-1.docker.io/idirouhab/n8n \\\n  --namespace n8n-production \\\n  --set database.host=postgres.example.com \\\n  --set database.passwordSecret.name=n8n-db-password \\\n  --set redis.host=redis.example.com \\\n  --set secretRefs.existingSecret=n8n-core-secrets \\\n  --set ingress.enabled=true \\\n  --set ingress.hosts[0].host=n8n.example.com\n```\n\n#### Development Environment\n\nUse the provided development configuration:\n\n```bash\n# Using git repository for development\ngit clone https://github.com/idirouhab/n8n-helm-chart.git\ncd n8n-helm-chart\nhelm install n8n ./charts/n8n -f values-dev.yaml\n\n# Or from OCI registry with custom values\nhelm install n8n oci://registry-1.docker.io/idirouhab/n8n -f my-dev-values.yaml\n```\n\n#### High Availability (Multi-Main Mode)\n\n```bash\nhelm install n8n oci://registry-1.docker.io/idirouhab/n8n \\\n  --set multiMain.enabled=true \\\n  --set multiMain.replicas=3 \\\n  --set queueMode.workerReplicaCount=4 \\\n  --set queueMode.workerConcurrency=15 \\\n  --set database.host=postgres.example.com \\\n  --set database.passwordSecret.name=n8n-db-password \\\n  --set redis.host=redis.example.com \\\n  --set secretRefs.existingSecret=n8n-core-secrets \\\n  --set ingress.enabled=true \\\n  --set ingress.hosts[0].host=n8n.example.com\n```\n\n#### Ultra High-Throughput (Webhook Processor Mode)\n\n```bash\nhelm install n8n oci://registry-1.docker.io/idirouhab/n8n \\\n  --set webhookProcessor.enabled=true \\\n  --set webhookProcessor.replicaCount=5 \\\n  --set queueMode.workerReplicaCount=10 \\\n  --set queueMode.workerConcurrency=20 \\\n  --set hpa.webhookProcessor.enabled=true \\\n  --set hpa.webhookProcessor.maxReplicas=100 \\\n  --set database.host=postgres.example.com \\\n  --set database.passwordSecret.name=n8n-db-password \\\n  --set redis.host=redis.example.com \\\n  --set secretRefs.existingSecret=n8n-core-secrets \\\n  --set ingress.enabled=true \\\n  --set ingress.hosts[0].host=n8n.example.com\n```\n\n## New Features\n\n### Enterprise Features\n- **License Management**: Support for n8n Enterprise licenses via secrets or direct configuration\n- **Multi-Main Setup**: Advanced leader election and coordination for multiple main instances\n\n### Storage \u0026 Scalability\n- **S3 External Storage**: Full S3 integration for binary data with configurable modes\n- **Advanced Redis Configuration**: Comprehensive Redis setup with cluster support, authentication, and fine-tuned worker settings\n- **Webhook Configuration**: Enhanced webhook support with custom URLs, timeouts, and testing endpoints\n\n### Execution Management\n- **Execution Control**: Configurable timeouts, data retention, and concurrency limits\n- **Data Pruning**: Automatic cleanup with configurable retention policies\n- **Worker Readiness**: Custom health checks for worker instances\n\n### Configuration Files\n- **Generic Values**: Clean `values.yaml` for easy customization\n- **Development Config**: Pre-configured `values-dev.yaml` for development environments\n\n## Configuration\n\n\n### Core Settings\n\n| Parameter          | Description                                             | Default     |\n| ------------------ | ------------------------------------------------------- | ----------- |\n| `replicaCount`     | Number of main pods (when multiMain.enabled=false)     | `1`         |\n| `image.repository` | n8n image repository                                    | `n8nio/n8n` |\n| `image.tag`        | n8n image version                                       | `1.110.1`   |\n| `nameOverride`     | Override chart name                                     | `\"\"`        |\n| `fullnameOverride` | Override full deployment name                           | `\"\"`        |\n\n### Queue Mode (Always Enabled)\n\n| Parameter                      | Description                                 | Default |\n| ------------------------------ | ------------------------------------------- | ------- |\n| `queueMode.workerReplicaCount` | Number of worker pods                       | `2`     |\n| `queueMode.workerConcurrency`  | Max concurrent jobs per worker              | `10`    |\n\n### Multi-Main Mode\n\n| Parameter            | Description                                    | Default |\n| -------------------- | ---------------------------------------------- | ------- |\n| `multiMain.enabled`  | Enable multiple main pods (optional)          | `false` |\n| `multiMain.replicas` | Number of main pods when enabled               | `2`     |\n\n### Webhook Processor Mode\n\n| Parameter            | Description                                    | Default |\n| -------------------- | ---------------------------------------------- | ------- |\n| `webhookProcessor.enabled`  | Enable dedicated webhook processing pods | `false` |\n| `webhookProcessor.replicaCount` | Number of webhook processor pods | `2`     |\n| `webhookProcessor.disableProductionWebhooksOnMainProcess` | Disable webhook processing in main pods | `true`     |\n\n### Database Configuration (Required)\n\n| Parameter                      | Description                    | Default                                    |\n| ------------------------------ | ------------------------------ | ------------------------------------------ |\n| `database.useExternal`         | Use external PostgreSQL (always true) | `true`                             |\n| `database.type`                | Database type                  | `postgres`                                 |\n| `database.host`                | PostgreSQL host (required)     | `\"\"`                                       |\n| `database.port`                | PostgreSQL port                | `5432`                                     |\n| `database.database`            | Database name                  | `n8n`                                      |\n| `database.schema`              | PostgreSQL schema name         | `\"public\"`                                 |\n| `database.user`                | Database user                  | `n8n`                                      |\n| `database.passwordSecret.name` | K8s secret containing password | `\"n8n-db-password\"`                        |\n| `database.passwordSecret.key`  | Key in secret for password     | `password`                                 |\n\n### Redis Configuration (Required)\n\n| Parameter                   | Description                    | Default                                    |\n| --------------------------- | ------------------------------ | ------------------------------------------ |\n| `redis.enabled`             | Enable Redis (always true)    | `true`                                     |\n| `redis.useExternal`         | Use external Redis (always true) | `true`                                  |\n| `redis.host`                | Redis host (required)          | `\"\"`                                       |\n| `redis.port`                | Redis port                     | `6379`                                     |\n| `redis.tls`                 | Enable TLS connection          | `false`                                    |\n| `redis.passwordSecret.name` | K8s secret containing password | `null`                                     |\n| `redis.passwordSecret.key`  | Key in secret for password     | `password`                                 |\n\n\u003e **⚠️ Important for AWS ElastiCache**: Set `redis.tls: true` when using AWS ElastiCache or other managed Redis services that require encrypted connections. Without TLS, queue mode initialization will fail and the UI may return 404 errors.\n\n### S3 Storage Configuration\n\n| Parameter                          | Description                           | Default      |\n| ---------------------------------- | ------------------------------------- | ------------ |\n| `s3.enabled`                       | Enable S3 external storage           | `false`      |\n| `s3.bucket.name`                   | S3 bucket name                        | `\"\"`         |\n| `s3.bucket.region`                 | S3 region                             | `\"\"`         |\n| `s3.bucket.host`                   | S3 endpoint (for S3-compatible)       | `\"\"`         |\n| `s3.auth.autoDetect`               | Use AWS credential provider chain (requires `serviceAccount.awsRoleArn`) | `false`      |\n| `s3.auth.accessKeyId`              | S3 access key ID                      | `\"\"`         |\n| `s3.auth.secretAccessKeySecret.name` | K8s secret containing secret key    | `\"\"`         |\n| `s3.auth.secretAccessKeySecret.key`  | Key in secret for secret key        | `\"\"`         |\n| `s3.storage.mode`                  | Binary data storage mode              | `filesystem` |\n| `s3.storage.availableModes`        | Available storage modes               | `filesystem` |\n\n#### S3 Secrets Setup\n\n```bash\n# Create S3 credentials secret\nkubectl create secret generic s3-credentials \\\n  --from-literal=aws-access-key-id=AKIAIOSFODNN7EXAMPLE \\\n  --from-literal=aws-secret-access-key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY\n\n# Use in values:\ns3:\n  enabled: true\n  bucket:\n    name: \"your-bucket\"\n    region: \"us-east-1\"\n  auth:\n    accessKeyId: \"AKIAIOSFODNN7EXAMPLE\"\n    secretAccessKeySecret:\n      name: \"s3-credentials\"\n      key: \"aws-secret-access-key\"\n```\n\n#### AWS IRSA Setup (Recommended for EKS)\n\nFor AWS EKS clusters, use IAM Roles for Service Accounts (IRSA) instead of access keys:\n\n```bash\n# 1. Create IAM policy for S3 access\naws iam create-policy \\\n  --policy-name n8n-s3-policy \\\n  --policy-document '{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n      {\n        \"Effect\": \"Allow\",\n        \"Action\": [\n          \"s3:GetObject\",\n          \"s3:PutObject\",\n          \"s3:DeleteObject\"\n        ],\n        \"Resource\": \"arn:aws:s3:::your-bucket/*\"\n      }\n    ]\n  }'\n\n# 2. Create IAM role with OIDC trust relationship\naws iam create-role \\\n  --role-name n8n-s3-role \\\n  --assume-role-policy-document '{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n      {\n        \"Effect\": \"Allow\",\n        \"Principal\": {\n          \"Federated\": \"arn:aws:iam::ACCOUNT-ID:oidc-provider/oidc.eks.REGION.amazonaws.com/id/CLUSTER-ID\"\n        },\n        \"Action\": \"sts:AssumeRoleWithWebIdentity\",\n        \"Condition\": {\n          \"StringEquals\": {\n            \"oidc.eks.REGION.amazonaws.com/id/CLUSTER-ID:sub\": \"system:serviceaccount:NAMESPACE:n8n\",\n            \"oidc.eks.REGION.amazonaws.com/id/CLUSTER-ID:aud\": \"sts.amazonaws.com\"\n          }\n        }\n      }\n    ]\n  }'\n\n# 3. Attach policy to role\naws iam attach-role-policy \\\n  --role-arn arn:aws:iam::ACCOUNT-ID:role/n8n-s3-role \\\n  --policy-arn arn:aws:iam::ACCOUNT-ID:policy/n8n-s3-policy\n\n# 4. Use in Helm values:\ns3:\n  enabled: true\n  bucket:\n    name: \"your-bucket\"\n    region: \"us-east-1\"\n  auth:\n    autoDetect: true  # \u003c-- Enable auto-detection\nserviceAccount:\n  awsRoleArn: \"arn:aws:iam::ACCOUNT-ID:role/n8n-s3-role\"  # \u003c-- IAM role ARN\n```\n\n**Environment Variables Set:**\nWhen S3 is configured, the following environment variables are automatically set:\n- `N8N_EXTERNAL_STORAGE_S3_HOST` (if host is specified)\n- `N8N_EXTERNAL_STORAGE_S3_BUCKET_NAME`\n- `N8N_EXTERNAL_STORAGE_S3_BUCKET_REGION`\n- `N8N_EXTERNAL_STORAGE_S3_ACCESS_KEY`\n- `N8N_EXTERNAL_STORAGE_S3_ACCESS_SECRET`\n- `AWS_ACCESS_KEY_ID` (for broader AWS SDK compatibility)\n- `AWS_SECRET_ACCESS_KEY` (for broader AWS SDK compatibility)\n- `N8N_DEFAULT_BINARY_DATA_MODE`\n- `N8N_AVAILABLE_BINARY_DATA_MODES`\n\n### Service Account Configuration\n\n| Parameter                          | Description                           | Default      |\n| ---------------------------------- | ------------------------------------- | ------------ |\n| `serviceAccount.create`            | Create service account                | `true`       |\n| `serviceAccount.name`              | Service account name                  | `n8n`        |\n| `serviceAccount.awsRoleArn`        | AWS IAM Role ARN for IRSA             | `\"\"`         |\n| `serviceAccount.annotations`       | Additional service account annotations | `{}`         |\n| `rbac.create`                      | Create RBAC resources                 | `true`       |\n\nThe chart supports three service account configuration scenarios:\n\n#### Scenario 1: Create New Service Account (Default)\nChart creates and manages the service account:\n```yaml\nserviceAccount:\n  create: true\n  name: \"n8n\"  # Custom name, or leave empty to use chart fullname\n```\n\n#### Scenario 2: Use Existing/Managed Service Account\nPerfect for Terraform-managed infrastructure where service accounts are created externally:\n```yaml\nserviceAccount:\n  create: false\n  name: \"my-terraform-service-account\"  # Name of existing service account\n```\n\n#### Scenario 3: No Service Account\nPods run with default Kubernetes permissions:\n```yaml\nserviceAccount:\n  create: false\n  name: \"\"  # Empty or omit entirely\n```\n\n**RBAC Permissions**: When `rbac.create: true`, the service account gets minimal required permissions:\n- **ConfigMaps**: `get`, `list` - For reading timezone and configuration\n- **Secrets**: `get`, `list` - For reading database passwords and encryption keys\n\n### Session Affinity (for Multi-Main)\n\nChoose ONE of the following approaches:\n\n#### Option 1: Ingress-Level (Recommended)\n\n```yaml\ningress:\n  annotations:\n    nginx.ingress.kubernetes.io/affinity: \"cookie\"\n    nginx.ingress.kubernetes.io/session-cookie-name: \"n8n-session\"\n    nginx.ingress.kubernetes.io/session-cookie-max-age: \"86400\"\n```\n\n#### Option 2: Service-Level\n\n```yaml\nservice:\n  sessionAffinity:\n    enabled: true\n    type: ClientIP\n    timeoutSeconds: 10800\n```\n\n### Persistence\n\n| Parameter | Description | Default |\n|-----------|-------------|---------|\n| `persistence.enabled` | Enable persistent volume | `true` |\n| `persistence.size` | Volume size | `10Gi` |\n| `persistence.storageClass` | Storage class | `\"\"` |\n\n### Autoscaling\n\n| Parameter | Description | Default |\n|-----------|-------------|---------|\n| `hpa.main.enabled` | Enable HPA for main pods (UI/API) | `false` |\n| `hpa.main.minReplicas` | Main minimum replicas | `1` |\n| `hpa.main.maxReplicas` | Main maximum replicas | `5` |\n| `hpa.main.targetCPUUtilizationPercentage` | Main target CPU % | `80` |\n| `hpa.worker.enabled` | Enable HPA for worker pods (execution) | `false` |\n| `hpa.worker.minReplicas` | Worker minimum replicas | `2` |\n| `hpa.worker.maxReplicas` | Worker maximum replicas | `20` |\n| `hpa.worker.targetCPUUtilizationPercentage` | Worker target CPU % | `70` |\n| `hpa.webhookProcessor.enabled` | Enable HPA for webhook processor pods | `false` |\n| `hpa.webhookProcessor.minReplicas` | Webhook processor minimum replicas | `2` |\n| `hpa.webhookProcessor.maxReplicas` | Webhook processor maximum replicas | `50` |\n| `hpa.webhookProcessor.targetCPUUtilizationPercentage` | Webhook processor target CPU % | `60` |\n\n## Advanced Configuration\n\n### Environment Variables\n\nThe chart supports all n8n environment variables through the `config.extraEnv` section in values.yaml. This provides a flexible way to configure any n8n setting.\n\n#### Basic Example\n\n```yaml\n# values.yaml\nconfig:\n  extraEnv:\n    - name: N8N_EDITOR_BASE_URL\n      value: \"https://n8n.example.com\"\n    - name: HTTP_PROXY\n      value: \"http://proxy.example.com:8080\"\n    - name: N8N_DISABLE_UI\n      value: \"false\"\n```\n\n#### Supported Environment Variables\n\n**Proxy Configuration**\n- `HTTP_PROXY` - Proxy URL for unencrypted HTTP requests\n- `HTTPS_PROXY` - Proxy URL for encrypted HTTPS requests\n- `ALL_PROXY` - Fallback proxy URL for all requests\n- `NO_PROXY` - Comma-separated list of hosts to bypass proxy\n\n\u003e **Note**: The proxy-from-env package used by n8n gives precedence to lowercase versions (e.g., `http_proxy` over `HTTP_PROXY`)\n\n**Core Configuration**\n- `N8N_EDITOR_BASE_URL` - Public URL where users access the editor\n- `N8N_CONFIG_FILES` - Path to JSON configuration file\n- `N8N_USER_FOLDER` - Path for n8n user data folder (default: `/home/node/.n8n`)\n- `N8N_PATH` - Path where n8n is deployed (default: `/`)\n\n**Feature Toggles**\n- `N8N_DISABLE_UI` - Set to `true` to disable the n8n UI\n- `N8N_PREVIEW_MODE` - Set to `true` to run in preview mode\n- `N8N_TEMPLATES_ENABLED` - Enable workflow templates (`true`/`false`)\n- `N8N_TEMPLATES_HOST` - Custom workflow templates API host\n- `N8N_PERSONALIZATION_ENABLED` - Show personalization questions (default: `true`)\n- `N8N_HIRING_BANNER_ENABLED` - Show hiring banner in console (default: `true`)\n\n**Network Configuration**\n- `N8N_HOST` - Host name n8n runs on (default: `localhost`)\n- `N8N_PORT` - HTTP port n8n runs on (default: `5678`)\n- `N8N_LISTEN_ADDRESS` - IP address to listen on (default: `::`)\n- `N8N_PROTOCOL` - Protocol: `http` or `https` (default: `http`)\n- `N8N_SSL_KEY` - SSL private key for HTTPS\n- `N8N_SSL_CERT` - SSL certificate for HTTPS\n- `N8N_PROXY_HOPS` - Number of reverse-proxies n8n is behind (default: `0`)\n\n**Telemetry \u0026 Notifications**\n- `N8N_DIAGNOSTICS_ENABLED` - Share anonymous telemetry (default: `true`)\n- `N8N_DIAGNOSTICS_CONFIG_FRONTEND` - Frontend telemetry configuration\n- `N8N_DIAGNOSTICS_CONFIG_BACKEND` - Backend telemetry configuration\n- `N8N_VERSION_NOTIFICATIONS_ENABLED` - Show version notifications (default: `true`)\n- `N8N_VERSION_NOTIFICATIONS_ENDPOINT` - Version check endpoint\n- `N8N_VERSION_NOTIFICATIONS_INFO_URL` - Update information URL\n\n**API Configuration**\n- `N8N_PUBLIC_API_DISABLED` - Disable public API (default: `false`)\n- `N8N_PUBLIC_API_ENDPOINT` - Public API path (default: `api`)\n- `N8N_PUBLIC_API_SWAGGERUI_DISABLED` - Disable Swagger UI (default: `false`)\n- `N8N_PUSH_BACKEND` - Backend push method: `websocket` or `sse` (default: `websocket`)\n\n**System Configuration**\n- `N8N_GRACEFUL_SHUTDOWN_TIMEOUT` - Shutdown timeout in seconds (default: `30`)\n- `N8N_ENCRYPTION_KEY` - Custom encryption key for credentials\n\n**Development Settings**\n- `N8N_DEV_RELOAD` - Auto-reload on code changes (default: `false`)\n- `N8N_REINSTALL_MISSING_PACKAGES` - Auto-reinstall missing packages (default: `false`)\n- `N8N_TUNNEL_SUBDOMAIN` - Custom subdomain for n8n tunnel\n\n**Frontend Build (Advanced)**\n- `VUE_APP_URL_BASE_API` - Frontend API base URL for manual builds\n\n#### Complete Configuration Example\n\n```yaml\n# values.yaml\nconfig:\n  extraEnv:\n    # Proxy configuration\n    - name: HTTP_PROXY\n      value: \"http://proxy.example.com:8080\"\n    - name: HTTPS_PROXY\n      value: \"https://secure-proxy.example.com:8443\"\n    - name: NO_PROXY\n      value: \"localhost,127.0.0.1,.example.com\"\n    \n    # Core settings\n    - name: N8N_EDITOR_BASE_URL\n      value: \"https://n8n.example.com\"\n    - name: N8N_USER_FOLDER\n      value: \"/home/node/.n8n\"\n    - name: N8N_PATH\n      value: \"/\"\n    \n    # Feature toggles\n    - name: N8N_TEMPLATES_ENABLED\n      value: \"true\"\n    - name: N8N_PERSONALIZATION_ENABLED\n      value: \"true\"\n    - name: N8N_HIRING_BANNER_ENABLED\n      value: \"false\"\n    \n    # Network configuration\n    - name: N8N_LISTEN_ADDRESS\n      value: \"::\"\n    - name: N8N_PROXY_HOPS\n      value: \"1\"\n    \n    # API settings\n    - name: N8N_PUBLIC_API_DISABLED\n      value: \"false\"\n    - name: N8N_PUBLIC_API_ENDPOINT\n      value: \"api\"\n    - name: N8N_PUSH_BACKEND\n      value: \"websocket\"\n    \n    # System settings\n    - name: N8N_GRACEFUL_SHUTDOWN_TIMEOUT\n      value: \"30\"\n    \n    # Development (only for dev environments)\n    - name: N8N_DEV_RELOAD\n      value: \"false\"\n```\n\n#### Using Secrets for Sensitive Data\n\n```yaml\nconfig:\n  extraEnv:\n    - name: N8N_EDITOR_BASE_URL\n      value: \"https://n8n.example.com\"\n    - name: CUSTOM_SECRET\n      valueFrom:\n        secretKeyRef:\n          name: n8n-secrets\n          key: custom-key\n```\n\n### Resource Limits\n\n```yaml\nresources:\n  main:\n    requests:\n      memory: \"512Mi\"\n      cpu: \"500m\"\n    limits:\n      memory: \"2Gi\"\n      cpu: \"2000m\"\n  worker:\n    requests:\n      memory: \"256Mi\"\n      cpu: \"250m\"\n    limits:\n      memory: \"1Gi\"\n      cpu: \"1000m\"\n```\n\n### Network Policies\n\n```yaml\nnetworkPolicy:\n  enabled: true\n  ingress:\n    - from:\n      - namespaceSelector:\n          matchLabels:\n            name: ingress-nginx\n```\n\n## Deployment Patterns\n\n### Pattern 1: Development\n\n- Queue mode (default)\n- 1 main pod, 1-2 worker pods\n- External PostgreSQL and Redis (lightweight instances)\n- Port-forward or ingress for access\n- Minimal resources\n\n### Pattern 2: Production - Standard\n\n- Queue mode (default)\n- 1 main pod, 2-4 worker pods\n- External PostgreSQL and Redis with high availability\n- Ingress with TLS\n- Persistence enabled\n- Resource limits configured\n\n### Pattern 3: Production - High Availability\n\n- Multi-main mode with queue\n- 2-3 main pods, 4-6 worker pods\n- External PostgreSQL with connection pooling\n- External Redis cluster\n- Ingress with session affinity\n- HPA enabled\n- PodDisruptionBudget configured\n\n### Pattern 4: Ultra High-Throughput Webhooks\n\n- Dedicated webhook processors + queue mode\n- 1-2 main pods (UI only), 5-20 webhook processors, 10-50 workers\n- Webhook processors handle all webhook traffic\n- Load balancer routes `/webhook/*` to webhook processors\n- All other traffic routes to main pods\n- Aggressive HPA scaling for webhook processors\n- External PostgreSQL and Redis clusters\n\n## Operations\n\n### Verify Deployment\n\n```bash\n# Check pods\nkubectl get pods -l app.kubernetes.io/name=n8n\n\n# Check services\nkubectl get svc -l app.kubernetes.io/name=n8n\n\n# View logs\nkubectl logs -f deployment/n8n-main\nkubectl logs -f deployment/n8n-worker\n```\n\n### Access n8n\n\n#### With Ingress\nNavigate to your configured host (e.g., https://n8n.example.com)\n\n#### Without Ingress (Port Forward)\n```bash\nkubectl port-forward svc/n8n 5678:5678\n# Access at http://localhost:5678\n```\n\n### Scaling\n\n```bash\n# Scale workers\nkubectl scale deployment n8n-worker --replicas=6\n\n# Scale main pods (only in multi-main mode)\nkubectl scale deployment n8n-main --replicas=3\n```\n\n### Upgrade\n\n```bash\n# Update chart values\nhelm upgrade n8n ./charts/n8n \\\n  --reuse-values \\\n  --set image.tag=new-version\n```\n\n### Backup\n\n```bash\n# Backup database\nkubectl exec -it postgres-pod -- pg_dump n8n \u003e n8n-backup.sql\n\n# Backup persistent volume\nkubectl cp n8n-pod:/home/node/.n8n ./n8n-backup\n```\n\n## Troubleshooting\n\n### Common Issues\n\n#### Pod crash-looping\n- Ensure secrets are created before deployment\n- Check database and Redis connectivity\n- Verify `N8N_ENCRYPTION_KEY` is set correctly\n\n#### Webhooks not working\n- Ensure `WEBHOOK_URL` is set to public URL\n- Verify ingress configuration\n- Check that all main pods can receive webhook requests\n\n#### Session issues in multi-main mode\n- Enable session affinity (see Session Affinity section)\n- Verify sticky session configuration at ingress\n\n#### Workers not processing jobs\n- Check Redis connectivity\n- Verify queue mode is enabled\n- Check worker logs for errors\n\n#### UI returns 404 errors via port-forward\n- **Most common cause**: Redis TLS configuration issue\n- Verify `redis.tls: true` is set.\n- Check Redis connection in main pod logs\n- Ensure Redis authentication is properly configured\n\n### Debug Commands\n\n```bash\n# Check pods status\nkubectl get pods -l app.kubernetes.io/name=n8n\n\n# View pod logs\nkubectl logs -f deployment/n8n-main\n\n# Check secrets exist\nkubectl get secrets | grep n8n\n```\n\n## Security Considerations\n\n1. **Always use external secrets** for sensitive data\n2. **Enable NetworkPolicies** in production\n3. **Use TLS** for ingress\n4. **Rotate encryption keys** regularly\n5. **Implement RBAC** for service accounts\n6. **Use PodSecurityPolicies** or Pod Security Standards\n7. **Enable audit logging** for compliance\n\n## Uninstall\n\n```bash\n# Remove the release\nhelm uninstall n8n\n\n# Clean up PVCs (data will be lost!)\nkubectl delete pvc -l app.kubernetes.io/name=n8n\n```\n\n## Support\n\n- **Chart Issues**: [GitHub Issues](https://github.com/idirouhab/n8n-helm-chart/issues)\n- **n8n Documentation**: [https://docs.n8n.io](https://docs.n8n.io)\n- **n8n Community**: [https://community.n8n.io](https://community.n8n.io)\n\n## License\n\nThis Helm chart is provided under the Apache 2.0 License. n8n itself is distributed under the [Sustainable Use License](https://github.com/n8n-io/n8n/blob/master/LICENSE.md).\n\n## Contributing\n\nContributions are welcome! Please:\n1. Fork the repository\n2. Create a feature branch\n3. Submit a pull request\n\nFor major changes, please open an issue first to discuss the proposed changes.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidirouhab%2Fn8n-helm-chart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fidirouhab%2Fn8n-helm-chart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fidirouhab%2Fn8n-helm-chart/lists"}