Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
23 changes: 23 additions & 0 deletions kubernetes/n8n-helm/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
32 changes: 32 additions & 0 deletions kubernetes/n8n-helm/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apiVersion: v2
name: n8n-helm
description: A Helm chart for deploying n8n on Kubernetes

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.44.0"

# Maintainers and sources can be added below if desired
# maintainers:
# - name: YourName
# email: [email protected]
# sources:
# - https://github.com/n8n-io/n8n
# - https://n8n.io/
53 changes: 53 additions & 0 deletions kubernetes/n8n-helm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# n8n Helm Chart

This Helm chart deploys [n8n](https://n8n.io/) and a PostgreSQL database on Kubernetes. All resources are fully parameterized for flexibility and production-readiness.

## Features
- Deploys n8n and PostgreSQL with configurable images, resources, and environment variables
- All secrets, config, and storage are templated and customizable
- Supports custom namespaces, service types, and ports

## Usage

### 1. Install the chart
```sh
helm install my-n8n ./n8n-helm -f my-values.yaml
```

### 2. Configuration
Edit `values.yaml` to customize:
- Namespace, PVCs, and storage
- n8n and Postgres images, tags, and resources
- Environment variables and secrets
- Service types and ports

Example:
```yaml
n8n:
image: n8nio/n8n
tag: 1.44.0
replicaCount: 1
# ...
postgres:
image: postgres
tag: "11"
# ...
```

### 3. Upgrade
```sh
helm upgrade my-n8n ./n8n-helm -f my-values.yaml
```

### 4. Uninstall
```sh
helm uninstall my-n8n
```

## Advanced
- All templates use Helm best practices for parameterization
- You can use conditionals or add subcharts for further customization

---

For more, see the official [n8n docs](https://docs.n8n.io/) and [Helm docs](https://helm.sh/docs/).
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
labels:
service: {{ .Values.pvc.label | default "n8n-claim0" }}
name: {{ .Values.pvc.name | default "n8n-claim0" }}
namespace: {{ .Values.namespace.name }}
spec:
accessModes:
- {{ .Values.pvc.accessMode | default "ReadWriteOnce" }}
resources:
requests:
storage: {{ .Values.pvc.storage | default "2Gi" }}
78 changes: 78 additions & 0 deletions kubernetes/n8n-helm/templates/n8n-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
service: n8n
name: n8n
namespace: {{ .Values.namespace.name }}
spec:
replicas: {{ .Values.n8n.replicaCount }}
selector:
matchLabels:
service: n8n
strategy:
type: Recreate
template:
metadata:
labels:
service: n8n
spec:
initContainers:
- name: volume-permissions
image: {{ .Values.n8n.initContainer.image }}
command: {{ toJson .Values.n8n.initContainer.command }}
volumeMounts:
- name: {{ .Values.pvc.name }}
mountPath: {{ .Values.n8n.initContainer.mountPath }}
containers:
- name: n8n
image: "{{ .Values.n8n.image }}:{{ .Values.n8n.tag }}"
command:
- /bin/sh
args:
- -c
- sleep 5; n8n start
env:
- name: DB_TYPE
value: "{{ .Values.n8n.env.DB_TYPE }}"
- name: DB_POSTGRESDB_HOST
value: "{{ .Values.n8n.env.DB_POSTGRESDB_HOST }}"
- name: DB_POSTGRESDB_PORT
value: "{{ .Values.n8n.env.DB_POSTGRESDB_PORT }}"
- name: DB_POSTGRESDB_DATABASE
value: "{{ .Values.n8n.env.DB_POSTGRESDB_DATABASE }}"
- name: DB_POSTGRESDB_USER
valueFrom:
secretKeyRef:
name: {{ .Values.n8n.secretRefs.DB_POSTGRESDB_USER.name }}
key: {{ .Values.n8n.secretRefs.DB_POSTGRESDB_USER.key }}
- name: DB_POSTGRESDB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.n8n.secretRefs.DB_POSTGRESDB_PASSWORD.name }}
key: {{ .Values.n8n.secretRefs.DB_POSTGRESDB_PASSWORD.key }}
- name: N8N_PROTOCOL
value: "{{ .Values.n8n.env.N8N_PROTOCOL }}"
- name: N8N_PORT
value: "{{ .Values.n8n.env.N8N_PORT }}"
ports:
- containerPort: 5678
resources:
requests:
memory: {{ .Values.n8n.resources.requests.memory }}
limits:
memory: {{ .Values.n8n.resources.limits.memory }}
volumeMounts:
- mountPath: {{ .Values.n8n.pvcMountPath }}
name: {{ .Values.pvc.name }}
restartPolicy: Always
volumes:
- name: {{ .Values.pvc.name }}
persistentVolumeClaim:
claimName: {{ .Values.pvc.name }}
- name: n8n-secret
secret:
secretName: n8n-secret
- name: postgres-secret
secret:
secretName: postgres-secret
22 changes: 22 additions & 0 deletions kubernetes/n8n-helm/templates/n8n-ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: n8n-ingress
namespace: {{ .Values.namespace.name }}
spec:
ingressClassName: {{ .Values.n8nIngress.ingressClassName }}
tls:
- hosts:
- {{ .Values.n8nIngress.host }}
secretName: {{ .Values.n8nIngress.tlsSecretName }}
rules:
- host: {{ .Values.n8nIngress.host }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ .Values.n8nService.name }}
port:
number: {{ .Values.n8nService.port }}
16 changes: 16 additions & 0 deletions kubernetes/n8n-helm/templates/n8n-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
labels:
service: {{ .Values.n8nService.selector.service }}
name: {{ .Values.n8nService.name }}
namespace: {{ .Values.namespace.name }}
spec:
type: {{ .Values.n8nService.type }}
ports:
- name: "{{ .Values.n8nService.port }}"
port: {{ .Values.n8nService.port }}
targetPort: {{ .Values.n8nService.targetPort }}
protocol: {{ .Values.n8nService.protocol }}
selector:
service: {{ .Values.n8nService.selector.service }}
4 changes: 4 additions & 0 deletions kubernetes/n8n-helm/templates/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: {{ .Values.namespace.name }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ .Values.postgresPvc.name }}
namespace: {{ .Values.namespace.name }}
spec:
accessModes:
- {{ .Values.postgresPvc.accessMode }}
resources:
requests:
storage: {{ .Values.postgresPvc.storage }}
16 changes: 16 additions & 0 deletions kubernetes/n8n-helm/templates/postgres-configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.postgresConfigMap.name }}
namespace: {{ .Values.namespace.name }}
data:
init-data.sh: |
#!/bin/bash
set -e;
if [ -n "${POSTGRES_NON_ROOT_USER:-}" ] && [ -n "${POSTGRES_NON_ROOT_PASSWORD:-}" ]; then
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER "${POSTGRES_NON_ROOT_USER}" WITH PASSWORD '${POSTGRES_NON_ROOT_PASSWORD}';
GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_DB} TO "${POSTGRES_NON_ROOT_USER}";
EOSQL
else
echo "SETUP INFO: No Environment variables given!"
81 changes: 81 additions & 0 deletions kubernetes/n8n-helm/templates/postgres-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
service: postgres-n8n
name: postgres
namespace: {{ .Values.namespace.name }}
spec:
replicas: {{ .Values.postgres.replicaCount }}
selector:
matchLabels:
service: postgres-n8n
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
service: postgres-n8n
spec:
containers:
- image: "{{ .Values.postgres.image }}:{{ .Values.postgres.tag }}"
name: postgres
resources:
limits:
cpu: {{ .Values.postgres.resources.limits.cpu }}
memory: {{ .Values.postgres.resources.limits.memory }}
requests:
cpu: {{ .Values.postgres.resources.requests.cpu }}
memory: {{ .Values.postgres.resources.requests.memory }}
ports:
- containerPort: 5432
volumeMounts:
- name: {{ .Values.postgresPvc.name }}
mountPath: {{ .Values.postgres.pvcMountPath }}
- name: init-data
mountPath: {{ .Values.postgres.configMapMountPath }}
subPath: {{ .Values.postgres.configMapSubPath }}
env:
- name: PGDATA
value: "{{ .Values.postgres.env.PGDATA }}"
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: {{ .Values.postgresSecret.name }}
key: POSTGRES_USER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.postgresSecret.name }}
key: POSTGRES_PASSWORD
- name: POSTGRES_DB
value: "{{ .Values.postgres.env.POSTGRES_DB }}"
- name: POSTGRES_NON_ROOT_USER
valueFrom:
secretKeyRef:
name: {{ .Values.postgresSecret.name }}
key: POSTGRES_NON_ROOT_USER
- name: POSTGRES_NON_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.postgresSecret.name }}
key: POSTGRES_NON_ROOT_PASSWORD
- name: POSTGRES_HOST
value: "{{ .Values.postgres.env.POSTGRES_HOST }}"
- name: POSTGRES_PORT
value: "{{ .Values.postgres.env.POSTGRES_PORT }}"
restartPolicy: Always
volumes:
- name: {{ .Values.postgresPvc.name }}
persistentVolumeClaim:
claimName: {{ .Values.postgresPvc.name }}
- name: postgres-secret
secret:
secretName: {{ .Values.postgresSecret.name }}
- name: init-data
configMap:
name: {{ .Values.postgresConfigMap.name }}
defaultMode: 0744
12 changes: 12 additions & 0 deletions kubernetes/n8n-helm/templates/postgres-secret.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Secret
metadata:
namespace: {{ .Values.namespace.name }}
name: {{ .Values.postgresSecret.name }}
type: Opaque
stringData:
POSTGRES_USER: {{ .Values.postgresSecret.user }}
POSTGRES_PASSWORD: {{ .Values.postgresSecret.password }}
POSTGRES_DB: {{ .Values.postgresSecret.db }}
POSTGRES_NON_ROOT_USER: {{ .Values.postgresSecret.nonRootUser }}
POSTGRES_NON_ROOT_PASSWORD: {{ .Values.postgresSecret.nonRootPassword }}
16 changes: 16 additions & 0 deletions kubernetes/n8n-helm/templates/postgres-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
labels:
service: {{ .Values.postgresService.selector.service }}
name: {{ .Values.postgresService.name }}
namespace: {{ .Values.namespace.name }}
spec:
clusterIP: {{ .Values.postgresService.clusterIP }}
ports:
- name: "{{ .Values.postgresService.port }}"
port: {{ .Values.postgresService.port }}
targetPort: {{ .Values.postgresService.targetPort }}
protocol: {{ .Values.postgresService.protocol }}
selector:
service: {{ .Values.postgresService.selector.service }}
Loading