Skip to main content

n8n

A self-hosted workflow automation platform with a visual node editor.

n8n is an open-source workflow automation tool that connects hundreds of apps and services via a visual drag-and-drop editor. It supports custom JavaScript/Python code nodes, webhooks, and scheduled triggers. Self-hosting means unlimited workflows, no per-execution pricing, and full data privacy.

Alternatives considered

Cloud Hosted

ToolOpen SourceFree TierMonthly Cost
ZapierNoLimitedFrom $19.99/mo
MakeNoLimitedFrom $9/mo
PipedreamNoLimitedFrom $29/mo

Installation

Architecture

  • Deployment: Single n8n deployment in the n8n namespace
  • Image: docker.n8n.io/n8nio/n8n:2.16.0 (digest-pinned)
  • Database: CNPG PostgreSQL cluster for workflow definitions and execution history
  • Storage: Longhorn PVC (n8n-data) for workflow data; emptyDir for cache
  • Networking: ClusterIP service on port 5678, HTTPRoute via internal gateway

Security

  • Runs as runAsUser: 1000, runAsNonRoot: true, readOnlyRootFilesystem: true, allowPrivilegeEscalation: false, capabilities dropped
  • Longhorn PVC encrypted at rest via SOPS-managed keys

Updates

Managed by Renovate. Image is digest-pinned.

Data Management

  • Database: CNPG PostgreSQL cluster (Longhorn-encrypted PVCs)
  • PVC: n8n-data (Longhorn-encrypted, k8up.io/backup: "true") for workflow data
  • Backups: k8up Schedule backs up Longhorn PVC and CNPG data to Hetzner S3. CNPG annotated with k8up.io/backupcommand: pg_dump.

User Management

No OIDC configured. User accounts managed through the n8n admin UI. N8N_RUNNERS_ENABLED configured for workflow execution.

Configuration Management

  • DB_TYPE, N8N_RUNNERS_ENABLED, base URL from ConfigMap env vars
  • Database credentials injected from CNPG-generated secret
  • Longhorn encryption key from SOPS-encrypted secret

Administration

Usage

Build automation workflows by connecting nodes (triggers, actions, transformations) in the visual editor. Use webhook nodes to trigger workflows from external services. Schedule recurring tasks with the cron trigger. The PostgreSQL backend stores workflow definitions and execution history.

Cluster-specific deviations from the above live in the per-cluster README — see k8s/apps/talos/n8n/README.md.

Cluster Deployment

n8n — Talos cluster

Cluster-specific notes only. General product info, "why we use it", and alternatives live in docusaurus/docs/apps/n8n.mdx.

Deviations from defaults

Defaults live in docusaurus/docs/apps/n8n.mdx — document anything this cluster does differently here, with a one-line reason.

Kubernetes Metadata
  • Image: docker.n8n.io/n8nio/n8n:2.26.3@sha256:51ac1d08178e635a593368f0947532990e55c14342ac781c8d77538daae859c8
Rendered manifests (kustomize build)
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kustomize.toolkit.fluxcd.io/force: enabled
labels:
app.kubernetes.io/instance: n8n
app.kubernetes.io/name: n8n
name: n8n
namespace: n8n
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/instance: n8n
app.kubernetes.io/name: n8n
ingress: public
strategy:
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/instance: n8n
app.kubernetes.io/name: n8n
ingress: public
spec:
containers:
- env:
- name: N8N_RUNNERS_ENABLED
value: 'true'
- name: VUE_APP_URL_BASE_API
value: https://n8n.web.kueber.e/
- name: DB_TYPE
value: postgres
- name: DB_POSTGRESDB_HOST
valueFrom:
secretKeyRef:
key: host
name: cnpg-app
- name: DB_POSTGRESDB_DATABASE
valueFrom:
secretKeyRef:
key: dbname
name: cnpg-app
- name: DB_POSTGRESDB_USER
valueFrom:
secretKeyRef:
key: user
name: cnpg-app
- name: DB_POSTGRESDB_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: cnpg-app
image: docker.n8n.io/n8nio/n8n:2.26.3@sha256:51ac1d08178e635a593368f0947532990e55c14342ac781c8d77538daae859c8
name: n8n
ports:
- containerPort: 5678
name: web
protocol: TCP
readinessProbe:
failureThreshold: 1
httpGet:
path: /
port: 5678
initialDelaySeconds: 2
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 2
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /home/node/.n8n
name: n8n-data
- mountPath: /home/node/.cache
name: n8n-cache
securityContext:
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
volumes:
- name: n8n-data
persistentVolumeClaim:
claimName: n8n-data
- emptyDir: {}
name: n8n-cache