Skip to main content

Phase 83 — n8n Workflow Automation

Deployed: 2026-08-01 | Version: n8n 2.32.7 | Namespace: automation

n8n is a self-hosted workflow automation platform — like Zapier or Make, but running entirely on the cluster. Workflows connect internal services (Plane, NATS, Stalwart mail, ERPNext, Backstage) and external APIs without sending data off-platform.


Three orchestration shapes — n8n vs Temporal vs Airflow​

These are not competitors — they are three different shapes of orchestration, chosen by the nature of the work, not preference. Picking the wrong one is the common mistake.

n8n (live)Temporal (live)Airflow (deferred, #153)
Shapeevent-driven integrationdurable stateful workflowscheduled batch DAG
Triggeran event/webhook happensa business process must run to completiona clock (cron / interval)
Built byanyone, visual UI (low-code)developers, in code (Go/TS/Py)developers, Python DAGs
Durabilitybest-effort + per-step retrydeterministic replay — survives crashes, resumes exactly, runs for days/months, saga/compensationtask-level retry within a run
Reach for it when…"when X happens, call Y and Z across APIs, retry/alert on failure" — glue, human-editablethe process is long-lived and must not lose state / must guarantee completion (e.g. claims-settlement saga: reserve → approve → SEPA payout → accounting → notify, rollback on failure)time-driven data/ML pipelines ("run the dbt transform nightly at 02:00")
On this clusterintegration glue: premium-collection lifecycle, SEPA/Stripe webhooks, notificationsdurable workflows: MAAS node power-dispatch/provisioning; the intended home for long insurance sagasnone yet — the analytical data platform (ClickHouse→dbt→BI) isn't built, so nothing needs cron DAGs; Airflow earns its place when it is

Litmus test: reactive glue → n8n; a transaction that must survive failure and complete → Temporal; a scheduled pipeline over data → Airflow. Two orchestrators are live (n8n + Temporal, each with a distinct role); the third is deferred until its use case (scheduled data pipelines) becomes real — see Temporal and Airflow.


Architecture​

https://n8n.devandre.sbs
│
Cloudflare Tunnel
│
ingress-nginx
│ (Authentik forward auth — nginx snippet pattern)
▼
n8n Deployment (automation ns)
│ SQLite on Longhorn 5Gi RWO PVC
│ Encryption key from Vault
▼
/webhook/ /webhook-test/ ← separate ingress, no auth
(for Plane/NATS/external triggers)
ComponentDetail
Imagedocker.io/n8nio/n8n:2.32.7
DatabaseSQLite on Longhorn RWO PVC (/home/node/.n8n)
Storagen8n-data PVC, 5Gi, longhorn StorageClass
AuthAuthentik forward auth (proxy provider pk 17, forward_single)
Webhooks/webhook/ and /webhook-test/ bypass Authentik (separate ingress)
TLScert-manager, ClusterIssuer minicloud-ca
SecretsESO → platform/n8n.encryption_key, platform/mail.smtp-relay-password
SMTPStalwart (stalwart.mail.svc.cluster.local:587), sender n8n@devandre.sbs
TimezoneEurope/Paris

GitOps layout​

manifests/n8n/
├── 00-namespace.yaml # automation namespace
├── 01-externalsecret.yaml # Vault → n8n-credentials secret
├── 02-pvc.yaml # 5Gi Longhorn RWO
├── 03-deployment.yaml # n8n Deployment
├── 04-service.yaml # ClusterIP :5678
├── 05-ingress.yaml # main (Authentik) + webhook (open)
└── 06-certificate.yaml # cert-manager TLS
apps/n8n.yaml # ArgoCD Application

Access​

URLAuth
https://n8n.devandre.sbsAuthentik OIDC (kanmegnea + TOTP) → n8n login
https://n8n.10.0.0.200.nip.ioInternal only (requires Tailscale)

Owner account: kanmegnea@gmail.com (set at first deploy via /rest/owner/setup).


Deployment gotchas​

1. Gatekeeper policy violations​

The cluster's OPA Gatekeeper enforces constraints that n8n's default pod spec violates:

PolicyFix
require-non-rootsecurityContext.runAsNonRoot: true, runAsUser: 1000
no-privilege-escalationsecurityContext.allowPrivilegeEscalation: false
block-net-rawsecurityContext.capabilities.drop: [NET_RAW]
require-resource-limitsresources.limits.cpu: 1000m

2. Node.js OOM at 512Mi​

n8n requires at least 1 GB RAM. The V8 heap exhausted at 512Mi:

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

Fix: memory limit 1.5Gi + NODE_OPTIONS=--max-old-space-size=1024.

3. Cloudflare tunnel requires a config.yml entry​

cloudflared tunnel route dns creates the DNS CNAME but does not add the ingress rule. Every new public hostname needs a manual entry in ~/.cloudflared/config.yml:

- hostname: n8n.devandre.sbs
service: https://10.0.0.200
originRequest:
noTLSVerify: true
originServerName: n8n.10.0.0.200.nip.io

Restart: pkill -f 'cloudflared tunnel' && nohup ~/.local/bin/cloudflared tunnel --config ~/.cloudflared/config.yml run >> ~/.cloudflared/cloudflared.log 2>&1 &


Authentik provider (rebuild reference)​

# Create proxy provider (forward_single)
curl -X POST https://auth.devandre.sbs/api/v3/providers/proxy/ \
-H "Authorization: Bearer $AK_TOKEN" -H "Content-Type: application/json" \
-d '{
"name":"n8n-forward-auth",
"authorization_flow":"3cb61a3d-47ba-47ac-bf32-b270179bb735",
"invalidation_flow":"2c1cd937-5a93-4e36-b9df-96839a9e3e05",
"external_host":"https://n8n.devandre.sbs",
"mode":"forward_single",
"property_mappings":["35c5c354-c9ce-4942-a919-43208923127f","06730f5f-cf59-4227-afe7-7fdf9dc113ba","d4967c11-acbe-4ae6-80c0-4b45c0fcf95b","677d145c-2abe-407e-9e5f-e425b65a8740","6e52eb60-9e8c-4684-be85-6cf79e894a01"],
"token_validity":"hours=24"}'
# → note the returned pk, then:
curl -X POST https://auth.devandre.sbs/api/v3/core/applications/ \
-d '{"name":"n8n","slug":"n8n","provider":<pk>,"meta_launch_url":"https://n8n.devandre.sbs"}'
# Add provider pk to embedded outpost providers list
curl -X PATCH https://auth.devandre.sbs/api/v3/outposts/instances/93d11dbf-e7fe-4604-afb1-7269980a5b47/ \
-d '{"providers":[1,8,15,<pk>]}'

Use cases on this platform​

  • Plane → Stalwart: email notifications for issue state transitions
  • ERPNext webhooks → NATS: publish HR events to the messaging bus
  • Monitoring alerts → custom logic: route Alertmanager webhooks beyond Slack
  • Scheduled exports: pull ERPNext/Plane data, format, send via Stalwart

Real-world skills demonstrated​

SkillIndustry context
Self-hosted workflow automationReplaces SaaS tools (Zapier, Make) for compliance-sensitive data
Authentik nginx forward authStandard proxy-auth pattern for internal tools without native OIDC
Separate webhook ingressProtect UI, expose API surface — same shape as Stripe/GitHub webhook receivers
Gatekeeper policy complianceEnforcing non-root, no NET_RAW, resource limits on third-party images
Vault-backed secrets at deployEncryption key injected from Vault — no plaintext in gitops