Skip to content
Workflow Automation with n8n
Workflow Automation with n8n

Workflow Automation with n8n

The cluster can reason, orchestrate, and generate media. But most real work is a chain of steps — fetch from an API, transform, call an Large Language ModelA model trained to predict text, served behind a chat or completion endpoint. On Frank these run locally on the GPU node rather than against a hosted provider., post the result, repeat on a schedule. That is workflow automation.

n8n is an open-source workflow automation platform with 400+ integrations, a visual node editor, and a webhook system. It runs as a single Node.js process backed by PostgreSQL.

    flowchart LR
  subgraph Authentik[Authentik — Forward Auth Proxy]
    BP[Blueprint ConfigMap<br/>forward_single proxy]
  end
  subgraph GPU1[gpu-1 — i9, 128GB RAM]
    subgraph n8nInstance[n8n-01 — per-user instance]
      n8n[n8n Deployment<br/>port 5678]
      PVC[10Gi PVC<br/>Longhorn<br/>/home/node/.n8n]
    end
    DB[paperclip-db-postgresql<br/>Bitnami PostgreSQL<br/>5Gi Longhorn]
  end
  subgraph Network
    LB[Service<br/>192.168.55.216:5678<br/>Cilium L2]
    Metrics[Prometheus /metrics<br/>scraped by VMAgent → Grafana]
  end

  BP -->|forward-auth| n8n
  n8n -->|DATABASE_URL| DB
  n8n --> Metrics
  LB --> n8n
  

Why Per-User Instances

n8n’s Community Edition does not support multi-user accounts with workflow isolation. Single Sign-OnOne login across many applications. On Frank, Authentik holds the session and Traefik asks it before forwarding a request. (OpenID ConnectAn identity layer on top of OAuth 2.0: it adds a token saying *who* the user is, not merely what the client may do. Frank's single sign-on speaks it, with Authentik as the provider./Security Assertion Markup LanguageThe XML-based single sign-on standard that predates OIDC. Still what many enterprise applications support, and only that.) is enterprise-only, gated behind a $400/month license. The pattern is simple: n8n-01, n8n-02, n8n-03 — each with its own namespace, PostgreSQL, PersistentVolumeClaimA Kubernetes request for durable storage. The pod names a claim and the storage layer — Longhorn on Frank — binds real disk behind it, so the data outlives the pod., and LoadBalancer IP. Adding an instance is a find-replace across ~6 files.

Why gpu-1

Not for the GPU — n8n does not request nvidia.com/gpu. gpu-1 has an i9 and 128GB RAM sitting mostly idle while Ollama and ComfyUI take turns with the RTX 5070. n8n tolerates the GPU taint but does not claim GPU resources.

Architecture

Two ArgoCD apps per instance:

ComponentTypePurpose
n8n-01Raw manifestsDeployment, Service (Load BalancerWhatever spreads traffic across backends and gives them one address. On Frank that is Cilium answering for an address on the LAN, not a cloud appliance.), PVC
n8n-01-postgresqlBitnami Helm chartStandalone PostgreSQL, Longhorn storage

Authentication: The OIDC Detour

n8n Community Edition gates OIDC behind enterprise. A community project (n8n-oidc) injects OIDC via external hooks — but no commits in three months and open issues with zero maintainer response.

The solution: Authentik forward-auth proxy, same pattern as Longhorn, Hubble, and Sympozium. A blueprint ConfigMap in authentik-extras:

- model: authentik_providers_proxy.proxyprovider
  identifiers:
    name: n8n-01
  attrs:
    mode: forward_single
    external_host: https://n8n-01.frank.derio.net

The Init Container That Wasn’t

The plan included an init container to bootstrap the admin account via n8n user:create. Community forums suggested this would work. It didn’t — n8n Community Edition has no user:create CLI command. The owner account must be created via the browser setup wizard on first access.

Secrets and Encryption

Three values in the Secrets OPerationSMozilla's tool for encrypting the *values* in a YAML file while leaving the keys readable, so an encrypted secret still reviews as a sensible diff.-encrypted secret secrets/n8n-01/n8n-01-secrets.yaml:

KeyPurpose
postgres-passwordPostgreSQL admin password
passwordPostgreSQL n8n user password
encryption-keyn8n credential encryption key

The encryption-key is critical. n8n uses it to encrypt stored API credentials. Without it set explicitly, n8n auto-generates one on the filesystem — lose the PVC, lose all credentials.

Metrics

n8n exposes Prometheus metrics at /metrics with N8N_METRICS=true:

annotations:
  prometheus.io/scrape: "true"
  prometheus.io/port: "5678"
  prometheus.io/path: "/metrics"

VMAgent auto-discovers these and feeds execution counts, durations, error rates into VictoriaMetrics → Grafana.

Adding Instances

  1. Copy apps/n8n-01/apps/n8n-<NN>/, find-replace n8n-01n8n-<NN>
  2. Copy apps/n8n-01-postgresql/apps/n8n-<NN>-postgresql/, find-replace
  3. Copy the 3 Application Custom ResourceAn object of a type Kubernetes did not ship with, added by a CRD. Frank's ArgoCD Applications, Rollouts and Tekton Pipelines are all CRs. templates, find-replace
  4. Pick next available IP from 192.168.55.2xx range
  5. Add proxy provider to blueprints-proxy-providers.yaml
  6. Create and encrypt secrets/n8n-<NN>-secrets.yaml
  7. Apply SOPS secret, commit, push

Missteps

What HappenedWhy It Was WrongHow We Fixed ItCommit
OIDC init planned but unworkable — n8n Community EditionThe free build of a product that also ships a paid one. Worth knowing which you are running: n8n CE has no SSO, and LiteLLM's CE image emits none of the Prometheus metrics its dashboards assume. has no user:create CLI command, OIDC is enterprise-onlyCommunity forums suggested user:create CLI exists; it does not in CESwitched to Authentik forward-auth proxy; removed init container
N8N_ENCRYPTION_KEY not set — auto-generated key stored on filesystem, all credentials unrecoverable on PVC lossDefault n8n behavior generates a key on first boot without persisting it explicitlyAdded N8N_ENCRYPTION_KEY from SOPS secret
RollingUpdate deadlocks on ReadWriteOnceA PVC access mode that lets exactly one node mount the volume read-write at a time. It is the reason a RollingUpdate deadlocks: the replacement pod cannot mount the volume until the outgoing pod releases it. PVC — new pod cannot attach while old pod holds the claimDefault strategy creates new pod before terminating old oneChanged to Recreate strategy

Recovery Path

SymptomCauseFix
Setup wizard appears on every accessUser account not createdComplete wizard once per instance — or create via n8n API
“Invalid credentials” for stored API keysN8N_ENCRYPTION_KEY changed — all encrypted creds invalidRestore original encryption key from SOPS secret
n8n redirects to Authentik login loopForward-auth proxy misconfigurationCheck external_host in blueprint ConfigMap
Pod stuck CreateContainerConfigErrorMissing SOPS secret not appliedCheck kubectl get secrets -n n8n-01

References

Next: Secure Agent Pod — Hardening an AI Workstation