Overview
n8n is a workflow automation platform (fair-code, distributed under n8n’s Sustainable Use License). This template deploys a single n8n instance serving the editor, REST API, and webhooks on one HTTPS endpoint, backed by a bundled PostgreSQL database — the postgres-highly-available template by default, or the single-instance postgres template for lighter installs. The instance owner account is pre-provisioned from a secret at install, so there is never an unauthenticated setup page. The owner login, the credential-encryption key and the database credentials come from secrets you create before installing; none passes through Helm values.What Gets Created
RELEASE_NAME-postgres-ha-*, RELEASE_NAME-etcd-*, RELEASE_NAME-patroni-startup, RELEASE_NAME-wal-g-backup-script); the single-instance database creates RELEASE_NAME-pg-identity and RELEASE_NAME-pg-policy.
Prerequisites
Three secrets must exist before you install. Secrets are org-level, so no GVC flag is involved.Create the encryption key secret
plain whose payload is a long random key. n8n encrypts every credential it stores with it:encryptionKey.secretName to this name. Back the key up outside Control Plane before installing — it can never be rotated. Everything n8n encrypts is bound to it: a changed key makes every stored credential undecryptable and n8n refuses to start on a key mismatch. Read it back any time with:Hash the owner password
htpasswd -B emits the $2y$ form, which n8n accepts:Create the owner secret
email and passwordHash:owner.secretName to this name.Create the database credentials secret
username, password and database. The bundled PostgreSQL initializes with it and n8n connects with it:credentialsSecretName of the database mode you use to this name — postgresHA.config.credentialsSecretName (default, HA) or postgres.config.credentialsSecretName (single-instance). PostgreSQL applies it only when its data directory is first initialized, so editing the secret later does not change the database password — see Rotating the Database Password. Secret names are org-wide, so give each n8n release its own.Installation
Once all three secrets exist, install from the marketplace registry with the three secret names:postgres.config.credentialsSecretName instead.
Or follow the instructions for your preferred method:
UI
CLI
Terraform
Pulumi
Configuration
n8n Instance
owner.firstName and owner.lastName are the owner’s display name and stay ordinary values; only the email and password hash live in the secret. The n8n image runs as a non-root user, and the chart makes the volume writable for it on first boot — nothing for you to do.
Access
publicAccess.enabled: false, the editor and webhooks are reachable only from inside the GVC (per internalAccess) or through a port-forward — see Connecting.
Database
Exactly one of the two database modes must be enabled; the chart refuses to render otherwise. The database credentials come from the prerequisite secret named by the enabled mode’scredentialsSecretName (see Prerequisites).
Database Backups
Backups are provided by the bundled database and are off by default. Set the block that matches your database mode and complete the storage setup first — see Backing Up.Connecting
The editor, REST API, and webhooks are all served on the n8n workload’s canonical endpoint, which is public by default (publicAccess.enabled: true). Read it from status.canonicalEndpoint:
CPLN_GLOBAL_ENDPOINT and sets N8N_HOST, N8N_WEBHOOK_URL, and N8N_EDITOR_BASE_URL to https://CANONICAL_ENDPOINT/. The URLs n8n shows in the editor are therefore the ones external callers use, with no extra configuration. With publicAccess.enabled: false those URLs still point at the canonical endpoint, which external callers cannot reach — in that mode, in-GVC callers use the internal address above, and you reach the editor through a port-forward:
http://localhost:5678. The port-forward path has not been exercised against an n8n install.
First Run
There is no setup wizard: the owner account already exists when n8n first starts. Openhttps://CANONICAL_ENDPOINT and sign in with the email from your owner secret and the password you hashed into passwordHash. The owner’s email and password cannot be changed from inside n8n — the secret is authoritative at every start — so change them through the secret instead (Rotating the Owner Password).
Operations
Backing Up
There are three things worth protecting, and they are protected differently. The encryption key. Without it, a restored database is full of credentials nobody can decrypt. Keep a copy outside Control Plane:postgresHA.backup or postgres.backup to match your database mode (see Database Backups) and complete the storage setup for your provider before installing. The bucket, cloud account, and IAM policy steps are the bundled database’s own, documented on its page: postgres-highly-available Backup Prerequisites for HA mode, postgres Backup Prerequisites for single mode. Set the values under the n8n keys shown above (postgresHA.backup.aws.bucket, not backup.aws.bucket).
In HA mode, postgresHA.backup.mode selects logical (scheduled pg_dump from a cron workload) or wal-g (continuous WAL archiving from a sidecar). Single mode takes scheduled logical dumps.
Backups to MinIO or another S3-compatible endpoint need one more prerequisite — a dictionary secret holding the keys accessKey and secretKey, created before install and named by postgresHA.backup.minio.credentialsSecretName or postgres.backup.minio.credentialsSecretName:
RELEASE_NAME-n8n-vs, mounted at /home/node/.n8n) holds instance config and binary execution data. The chart configures a final snapshot when the volume set is deleted, with snapshots retained for 7 days. Take one on demand with:
Restoring a Backup
Restoring the database follows the bundled database’s own procedure, run from a client with access to the backup bucket: postgres-highly-available Restoring a Backup in HA mode (connect throughRELEASE_NAME-postgres-ha-proxy.GVC_NAME.cpln.local so the restore targets the current leader), or postgres Restoring a Backup in single mode (host RELEASE_NAME-postgres.GVC_NAME.cpln.local). The username and password are in your database credentials secret.
Two n8n-specific points:
- The restored database only yields usable credentials if the instance runs with the same encryption key the backup was taken under. Create the encryption key secret with the saved key before pointing a new install at restored data.
- Workflows, credentials, and execution records live in the database; files under
/home/node/.n8n(binary execution data) are on the volume set and are not part of a database dump.
Rotating the Owner Password
Because n8n re-applies the owner from the secret on every start, the owner password is rotated by changing the secret and restarting the workload — not from inside n8n. Hash the new password, apply the whole secret with the new hash, then force a redeployment (a changed secret is only picked up when the replica restarts):ENCRYPTION_KEY_SECRET_NAME’s payload after first boot makes every stored credential undecryptable and n8n refuses to start.
Upgrading From 1.0.x
Version1.1.0 moved the instance owner out of Helm values. 1.0.0 and 1.0.1 took owner.email and owner.password as values, used exactly as written, guarding a login form that is public by default.
helm upgrade that still carries either removed key is refused at render, before anything is applied, and the error names the replacement:
Create the owner secret
Drop the removed keys from your values
owner.email and owner.password and set owner.secretName. Leave encryptionKey.secretName, owner.firstName, and owner.lastName as they are.Continue with the later sections
Upgrading From 1.1.0
Version1.2.0 changed how the single-instance database (postgres.enabled: true) gets its credentials. postgres.config.username, postgres.config.password, and postgres.config.database were removed; the same three values now live in the database credentials secret under Prerequisites, named by postgres.config.credentialsSecretName. Carrying the old keys fails at render with the bundled database’s own message:
postgres.config.* into that secret, keeping them identical to what the running database was initialised with — the message’s advice to create a secret is correct here. postgres.backup.minio.accessKey and secretKey were removed in the same version: backups to MinIO now need the prerequisite dictionary secret described in Backing Up, named by postgres.backup.minio.credentialsSecretName. Installs in HA mode have nothing to change in this step.
Upgrading From 1.2.0 or 1.3.0
Version1.3.0 moved the highly available database (postgresHA.enabled: true, the default) to the same credentials model, and 1.3.1 completed it for MinIO backups. postgresHA.postgres.username, postgresHA.postgres.password, and postgresHA.postgres.database no longer exist; the HA database now reads the database credentials secret under Prerequisites, named by postgresHA.config.credentialsSecretName. Carrying the old block fails at render:
Move the credentials
postgresHA.postgres.* from your values and put the same three values into the database credentials secret as the keys username, password and database.Name the secret
postgresHA.config.credentialsSecretName to the secret’s name. Secret names are org-wide, so give each n8n release in the org its own.MinIO backups only
postgresHA.backup.minio.accessKey and secretKey were removed. Create the prerequisite dictionary secret described in Backing Up and set postgresHA.backup.minio.credentialsSecretName to its name. 1.3.0 still listed the two removed keys in its values while the bundled database already refused them, which is why MinIO backups in HA mode need 1.3.1.Upgrade
cpln helm upgrade with the updated values. The single n8n replica restarts, and the first upgrade after an install can also restart the bundled database — expect the editor and webhooks to be briefly unavailable. Workflows, credentials, and execution data are untouched.change-me-n8n-db-password, treat it as compromised and change it after the upgrade — see Rotating the Database Password.
Upgrading From 1.3.1
Version1.4.0 removed postgres.credentials: the database credentials are now a prerequisite secret, the same one the bundled database template requires on its own. Carrying the old key forward fails the render.
1.3.1 created the database secret itself, so this upgrade deletes it. Before upgrading, create a secret under a new name holding the values your database was initialized with — not new ones, or n8n loses its database connection:
credentialsSecretName of your database mode (postgresHA.config. or postgres.config.) set to that name and postgres.credentials removed. Your current values are in postgres.credentials of the 1.3.1 release, and also in the old secret (cpln secret reveal SECRET_NAME -o yaml, where SECRET_NAME is the credentialsSecretName your release used, my-n8n-db-credentials by default) until the upgrade deletes it.
The upgrade restarts the bundled PostgreSQL too (it now reads the new secret), so n8n can briefly lose its database; it reconnects by itself. While access to the new secret propagates, the new version of a workload can wait in get-deployments reporting that it is not allowed to reveal the secret; the previous version keeps serving meanwhile, and it clears by itself.
Upgrading From 1.4.0
n8n moves from 2.29.8 to 2.45.4 and migrates its database on the first start. Rolling back to1.4.0 is not supported, so back up the database first. The chart refuses any n8nio/n8n tag below 2.45.4, so if your values pin image, set it to n8nio/n8n:2.45.4 or remove it. Schedule Triggers set to “every N seconds/minutes” now run N apart from when the workflow was activated, instead of on clock boundaries.
In HA mode the database moves to controlplanecorporation/patroni-postgres:0.8, which carries pgvector 0.8.7. The database members restart and nothing limits that rollout, so expect a brief interruption of writes while the leader changes; n8n itself restarts as on any upgrade, which is the longer interruption, because its single replica stops before the new one serves. Upgrade in a quiet window. If your values set postgresHA.image, set it to the 0.8 tag: tags 0.1 to 0.7 are refused at render. n8n’s own tables do not use the vector extension, but a PGVector Vector Store node pointed at this database creates it. If it exists, run this in that database after the upgrade:
Rotating the Database Password
A running workload keeps the credential values it started with, and PostgreSQL reads the secret only when its data directory is first initialized, so editing the secret alone does not change the database password. Change one key and keep the others with export, edit, apply:ALTER ROLE for the secret’s username in the database first, then update the secret, then right away force a redeployment of RELEASE_NAME-n8n. Do not redeploy the database; restarting it only adds downtime.
repl shares the password, and a member that restarts with the old password can be promoted to leader, which splits the cluster. Move the leader to member -0 first, so it restarts last, after every other member already has the new password. pgx runs a command in one member (LOCATION is your GVC’s location, DB_USERNAME the secret’s username):
RELEASE_NAME-n8n, which keeps the old password until it restarts. The app cannot open new database connections from the ALTER ROLE until its own redeploy finishes, so rotate in a quiet window. If a member stays starting, or running without streaming, re-copy it from the leader. This copies the whole database, so it costs network traffic in proportion to its size:
Scaling and Availability
- n8n runs as a single replica (
maxScale: 1) by upstream design for the standard mode this template ships; the knob to grow isresources, not a replica count. - The database is highly available by default —
postgresHA.replicas: 3Patroni replicas with automatic failover behind an HAProxy leader endpoint, so a database node loss does not take n8n down. SetpostgresHA.enabled: falseandpostgres.enabled: truefor a single-instance database when availability matters less than footprint. - Every
helm upgraderestarts the single n8n replica, so the editor and webhooks are briefly unavailable; the first upgrade after an install can also restart the bundled database. - Volume capacity: grow
volumeset.capacity(n8n) orpostgresHA.volumeset.capacity/postgres.volumeset.capacity(database) in GiB; the minimum is 10.
Troubleshooting
The n8n workload never starts and cpln logs returns nothing
The n8n workload never starts and cpln logs returns nothing
cpln workload force-redeployment RELEASE_NAME-n8n --gvc GVC_NAME to skip the wait.Install refused with enable exactly one database
Install refused with enable exactly one database
postgresHA.enabled and postgres.enabled to true. The HAProxy endpoint must stay on in HA mode (postgresHA.proxy.enabled is refused when false).Install refused because a key was REMOVED
Install refused because a key was REMOVED
owner.email / owner.password (removed in 1.1.0), postgres.config.username / password / database (removed in 1.2.0), postgresHA.postgres.* and *.backup.minio.accessKey / secretKey (removed in 1.3.0 / 1.3.1), or postgres.credentials (removed in 1.4.0). The render fails before anything is applied, and the running release is untouched. Fix: follow the matching section under Operations, starting with Upgrading From 1.0.x.My password stopped working after an upgrade or restart
My password stopped working after an upgrade or restart
n8n fails to start after the encryption key secret changed
n8n fails to start after the encryption key secret changed
N8N_ENCRYPTION_KEY no longer matches the key the instance was first started with; n8n refuses to start on a mismatch. Fix: put the original key back in the encryption key secret and force a redeployment. If the original key is gone, the stored credentials cannot be recovered — start a fresh install and re-enter them.Webhook callers receive a 504
Webhook callers receive a 504
timeoutSeconds on the workload). The workflow still completes. Fix: set the Webhook node to respond immediately or add a Respond to Webhook node early in the workflow.n8n restarts a few times right after install
n8n restarts a few times right after install
cpln workload get-deployments RELEASE_NAME-n8n --gvc GVC_NAME -o yaml never reports ready.Important Notes
- Back up the encryption key secret before installing — it cannot be rotated; losing or changing it makes every stored credential undecryptable and n8n fails to start on a mismatch.
- Create all three prerequisite secrets before installing — a missing one wedges the deployment with no log output;
cpln workload get-deployments RELEASE_NAME-n8n --gvc GVC_NAME -o yamlis the one command that names it. - The owner secret is the login at every restart — change the password through the secret plus a forced redeployment, never from inside n8n, and when upgrading hash the password you use today.
- Editing the database credentials secret does not change the database password — run
ALTER ROLEfirst, then force-redeploy n8n; in HA mode move the leader first (Rotating the Database Password). - Give each n8n release its own database credentials secret — secret names are org-wide, so two releases pointed at one secret share a password.
- Synchronous webhook responses must finish within 30 seconds — see Connecting.
- Every upgrade restarts the single n8n replica — expect a brief editor and webhook outage; the first upgrade after an install can also restart the bundled database.
- Uninstall deletes the database and n8n volume sets — all workflows, credentials, and execution data; enable backups if the data matters.
- n8n is fair-code under the Sustainable Use License — free to self-host, not OSI open source.