Overview
Unleash is an open-source feature-flag server: toggle features on and off, roll them out gradually and run A/B tests without redeploying the applications that use them. This template deploys the free open-source edition as one stateless workload serving the admin UI and the Admin, Client and Frontend APIs on a single port, backed by a bundled PostgreSQL database that holds every flag, user and token — the postgres-highly-available template by default, or the single-instance postgres template with one flag. Because other applications gate their behaviour on it, the highly available database is the default, and the Unleash server itself scales to more replicas with a single value.What Gets Created
Prerequisites
Two secrets must exist before you install, and a third is optional. They hold credentials, so they are prerequisite secrets rather than values — a value would sit in plaintext in the Helm release for the life of the install. Secrets are org-level, so no--gvc flag is involved.
Create the admin login secret (required)
username and password. It seeds the initial admin account, whose login form sits on the public endpoint, so it is a prerequisite secret rather than a Helm value:admin.secretName to this name. Read the values back later with cpln secret reveal ADMIN_SECRET_NAME -o yaml — the -o yaml is required; a bare reveal prints only a summary table.Create the API-token seed secret (optional)
backend and frontend, each a full Unleash token string in the format <project>:<environment>.<secret>. The open-source edition ships the default project and the development and production environments:apiTokens.secretName to this name. Leaving it empty (the default) turns seeding off entirely.Create the database credentials secret (required)
username, password and database. The bundled PostgreSQL initializes with these values and Unleash connects with them:postgresHA.config.credentialsSecretName (HA, the default) or postgres.config.credentialsSecretName (single-instance). PostgreSQL reads the secret only when its data is first initialized; to change the password later, change it in the database first, then update the secret and force a redeployment of the Unleash workload.Installation
Once the admin and database credentials secrets exist, install the template into your GVC, naming them:--set apiTokens.secretName=API_TOKENS_SECRET_NAME if you created the optional token seed. If you run more than one release of this template in the same org, create a separate database credentials secret for each — see Database.
UI
CLI
Terraform
Pulumi
Configuration
Unleash Instance
resources.maxCpu and resources.maxMemory are the container limits; resources.minCpu and resources.minMemory are the reservation. replicas sets a fixed replica count behind the load balancer — the server holds no state of its own, so 2 or more keeps flags served through a rolling restart or the loss of one replica. Unleash’s version check against the upstream service is disabled by the template.
Admin Account and API Tokens
admin.secretNamenames the required dictionary secret from Prerequisites, with keysusernameandpassword. Unleash creates the admin account from it on first boot only; the account then lives in the database. Editing the secret later changes nothing, and an upgrade never resets the password — change it in the admin UI.apiTokens.secretNamenames the optional dictionary secret with keysbackendandfrontend. When set, both tokens are seeded on first boot only; when empty, nothing is seeded and the workload references no extra secret. Create or revoke tokens later in the admin UI.
Access
/api/frontend and /api/client directly. Every surface is authenticated — the UI and Admin API by login, the Client and Frontend APIs by tokens. Set publicAccess.enabled: false for an internal-only instance; in-GVC callers still reach it per internalAccess, and you reach the UI through a tunnel (see Connecting). A firewall change can take a few minutes to take effect, so re-test rather than trusting the first response.
The URL Unleash embeds in password-reset and invite links is derived at container start: the canonical endpoint when public, the internal RELEASE_NAME-unleash.GVC_NAME.cpln.local:4242 address when not.
Database
Exactly one of the two database modes must be enabled — the chart enforces this at render and refuses to install otherwise. Unleash is wired to the active database automatically: the HAProxy leader endpoint in HA mode, or the single instance directly.postgresHA.config.credentialsSecretName or postgres.config.credentialsSecretName (whichever database is enabled); the database initializes from it and Unleash connects with it. In HA mode the proxy must stay enabled — that endpoint is Unleash’s stable database address, and the chart refuses to render with postgresHA.proxy.enabled: false.
Secret names are org-wide, so if you run more than one release of this template in the same org, create a separate database credentials secret for each and point each release’s credentialsSecretName at its own.
Everything else the bundled databases can do — volume autoscaling, PgBouncer pooling, etcd tuning — is documented on the postgres-highly-available and postgres pages and is set under the same postgresHA.* / postgres.* prefixes. Their backup settings are covered under Backing Up.
Connecting
status.canonicalEndpoint, then confirm the server answers — /health returns HTTP 200 once Unleash has finished its database migrations:
publicAccess.enabled: false there is no canonical endpoint. Open a tunnel to the UI instead and browse to http://localhost:4242:
First Run
Unleash has no setup wizard: the admin account is created from your admin secret on first boot. A fresh install in HA mode takes several minutes to become ready while the database cluster forms; the start script waits until the database accepts queries before Unleash runs its migrations.Wait for the workload to report ready
Sign in
http://localhost:4242 through the tunnel) and sign in with the username and password from your admin secret. Change the password in the UI if you wish — that is the only place it changes from now on.Create an SDK token
apiTokens.secretName, go to Admin → API access and create one: choose Backend for a server-side SDK or Frontend for a browser or mobile SDK, then the project and environment it applies to.API Tokens
SDKs authenticate with an API token in theAuthorization header, and the two token types are not interchangeable:
- Backend tokens authenticate server-side SDKs against
/api/client. Treat them like passwords. - Frontend tokens authenticate browser and mobile SDKs against
/api/frontend. They are designed to be embedded in client code.
<project>:<environment>.<secret>), so a 401 or 403 from an SDK API usually means the wrong token type for the endpoint or the wrong environment in the token.
Operations
Backing Up
Database backups are optional and disabled by default. They cover the database — every flag, strategy, segment, user and token in your Unleash instance. Enable them on whichever database is active and complete the storage setup for your provider before installing or upgrading with them on.postgresHA.backup.mode selects logical (a scheduled dump run by the RELEASE_NAME-postgres-ha-backup cron workload through the HAProxy endpoint) or wal-g (continuous WAL archiving from the database workload itself, with no separate backup workload). The single-instance database takes scheduled logical dumps only, through RELEASE_NAME-postgres-backup. Both come from the bundled postgres-highly-available and postgres templates. The steps below name the keys under postgresHA.backup.*; in single-instance mode set the same keys under postgres.backup.*.
- AWS S3
- Google Cloud Storage
- MinIO / S3-compatible
Create a bucket
postgresHA.backup.aws.bucket and postgresHA.backup.aws.region to match.Set up a Cloud Account
postgresHA.backup.aws.cloudAccountName to its name.Create a bucket-scoped IAM policy
YOUR_BUCKET), then set postgresHA.backup.aws.policyName to the policy’s name:Restoring a Backup
.sql.gz under your prefix), replayed with psql from a client that can reach both the bucket and the database — a workload inside the GVC, or your own machine with a tunnel open. The Unleash container is not that client. In HA mode go through the HAProxy endpoint so the writes land on the leader:
RELEASE_NAME-postgres as the workload name in single-instance mode. The full per-provider replay commands, and the WAL-G outline for HA mode — which ends in a manual volume-set swap this chart does not expose — are on the postgres-highly-available and postgres pages. Restore into an empty database and keep Unleash from connecting until the replay has finished. Because the restored database already holds an admin account, the admin secret is not applied again — sign in with the account from the dump.
Upgrading from 1.0.x
Two changes landed between 1.0.0 and 1.1.0; apply both when upgrading from 1.0.0. 1.0.1 — etcd compaction. Version 1.0.0 did not compact the etcd cluster inside the bundled highly available database, so etcd’s backend grows with time alone and eventually goes read-only when it reaches its quota — taking PostgreSQL failover with it. Only installs running the HA database are affected (postgresHA.enabled, the default). See etcd History Compaction for the mechanism and symptoms. Upgrading to 1.0.1 or later turns compaction on; that stops further growth but cannot shrink a backend that has already grown, and a cluster that has already raised a NOSPACE alarm needs operator recovery rather than an upgrade.
1.1.0 — the admin login became a prerequisite secret. Earlier versions shipped admin.username and a working admin.password as values — a published default guarding a login form on the public endpoint. An upgrade that still carries either key is rejected at render, before anything is applied, with a message naming its replacement; there is no compatibility fallback. Version 1.1.0 also made the start script wait for the database before Unleash runs its migrations.
Create the admin login secret
apiTokens.secretName secret stays exactly as it is.Drop the removed keys and upgrade
admin.username and admin.password from your values and set admin.secretName. The Unleash replicas restart; flags, users and tokens are in the database and are untouched.Change the admin password in the UI
change-me-unleash-admin), treat it as compromised and change it now in the Unleash UI — the secret cannot change an existing account. Every later migration note below also applies.Upgrading from 1.1.0
Version 1.2.0 adopted thepostgres 3.4.1 template, which stopped taking database credentials as values. In single-instance mode three keys were removed:
postgres.config.credentialsSecretName to its name, and remove the three keys. A values file that still carries an old key fails the render with the postgres template’s message (config.username was REMOVED in postgres 3.4.0). If you back up to MinIO, create the dictionary secret described under Backing Up and set postgres.backup.minio.credentialsSecretName. The HA path is unchanged by this step.
Upgrading from 1.2.x
Version 1.3.0 adopted thepostgres-highly-available 2.5.0 template, which made the same change on the HA path, and 1.3.1 did the same for its MinIO backup keys. The HA database credentials now come from the database credentials secret named by postgresHA.config.credentialsSecretName.
postgresHA.config.credentialsSecretName to its name, and delete the postgresHA.postgres block entirely. A values file that still carries the old block stops the upgrade at render:
postgresHA.backup.minio.credentialsSecretName, and remove the two old keys; if you are already on 1.3.0, that MinIO change is the only part of this step that applies.
Upgrading from 1.3.x
Version 1.4.0 renamed the Unleash container’s resource limits: a block that exposes both a reservation and a limit now names the limitmaxCpu / maxMemory, so it is no longer ambiguous which number is the ceiling. Nothing else changed.
unleash: resources.cpu was RENAMED to resources.maxCpu (or the memory equivalent); rename the two keys and upgrade. resources.minCpu and resources.minMemory keep their names, and the backup resources blocks, which expose only a limit, keep cpu and memory.
Upgrading from 1.4.0
Version 1.5.0 removedpostgres.credentials: the database credentials are now a prerequisite secret, the same one the database templates require on their own. Carrying the old key forward fails the render.
1.4.0 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 Unleash loses its database connection:
postgresHA.config.credentialsSecretName (HA mode) or postgres.config.credentialsSecretName (single-instance mode) set to that name, and postgres.credentials removed. Your current values are in postgres.credentials of the 1.4.0 release, and also in the old secret (cpln secret reveal my-unleash-db-credentials -o yaml, or the name your release set in credentialsSecretName) until the upgrade deletes it.
The upgrade restarts the bundled PostgreSQL too (it now reads the new secret), so Unleash can briefly lose its database; it reconnects by itself. The new version of a workload can also wait for several minutes, with get-deployments reporting that it is not allowed to reveal the secret, while access to the new secret propagates; the previous version keeps serving meanwhile, and it clears by itself.
Upgrading from 1.5.0 or earlier
1.5.1 moves the HA database (postgresHA) to controlplanecorporation/patroni-postgres:0.8, which carries pgvector 0.8.7 (CVE-2026-103484). The fix takes effect when the upgrade restarts the Patroni members; existing data needs nothing. Nothing limits that rollout, so expect a brief interruption of writes while the leader changes. Unleash itself restarts without a gap: the new replica serves before the old one stops. Upgrade in a quiet window. If you pinned postgresHA.image in your values, set it to the 0.8 tag: tags 0.1 to 0.7 are refused at render. Unleash does not use the vector extension; if you created it yourself in a database, \dx keeps reporting the old version until you run ALTER EXTENSION vector UPDATE; there, which only updates that record. Single-instance mode (postgres) is unchanged.
Rotating the Database Password
PostgreSQL reads the database credentials secret only when its data is first initialized, and a running workload keeps the values it started with. In single-instance mode, change the password in the database first (ALTER ROLE DB_USERNAME PASSWORD 'NEW_PASSWORD';), then update the secret with cpln secret edit SECRET_NAME and force a redeployment of the Unleash workload:
Rotating the Database Password in HA Mode
The HA database (postgresHA) needs its own order. The replication role 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-unleash, which keeps the old password until it restarts. The database drops connections briefly at each switchover, and the app cannot open new 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 for several minutes, re-copy it from the leader. This copies the whole database, so it costs network traffic in proportion to its size:
Scaling and Availability
- The Unleash server is stateless — set
replicasto2or more so flags keep being served through a rolling restart or the loss of a replica. Every Helm upgrade rolls the Unleash replicas. - Database replicas are set with
postgresHA.replicas; the single-instance database must stay at one replica. - The first
helm upgradeafter an install can restart the bundled database even when no database value changed, so expect a short interruption on that first upgrade. - Seeded secrets apply on first boot only. Editing the admin or API-token secret later does not change the account or the tokens; manage both in the admin UI.
- Confirm an upgrade is live from the deployment, not from the Helm output —
cpln workload get-deployments RELEASE_NAME-unleash --gvc GVC_NAME -o yaml. - Uninstall deletes every volume set the chart created — the database and, in HA mode, the consensus store — so the data does not survive a reinstall. The GVC is yours and is left alone, and the prerequisite secrets you created survive. Enable backups if the data matters.
Troubleshooting
The Unleash workload never starts after install while helm reported success
The Unleash workload never starts after install while helm reported success
cpln helm install succeeded, but RELEASE_NAME-unleash shows no running containers and cpln logs returns nothing.Cause: A prerequisite secret named in your values does not exist — the admin secret, the database credentials secret, or the API-token secret when apiTokens.secretName is set. The deployment pauses on the unresolved reference.Fix: Read the message naming the secret, then create it:The secret <name> no longer exists. Workload updates are paused until the secret is added or the reference to the secret removed. Once the secret exists the deployment recovers on its own, or run cpln workload force-redeployment RELEASE_NAME-unleash --gvc GVC_NAME to skip the wait.Failed to migrate db errors on a fresh install in HA mode
Failed to migrate db errors on a fresh install in HA mode
RELEASE_NAME-unleash is not ready yet and its logs contain Failed to migrate db.Cause: Unleash cannot run its schema migrations until the bundled database cluster has formed and the HAProxy endpoint routes to a leader. Transient migration errors while the cluster starts are expected and self-correcting, at any replica count.Fix: Wait, then re-check cpln workload get-deployments RELEASE_NAME-unleash --gvc GVC_NAME -o yaml. Confirm the database tier is ready first with cpln workload get-deployments RELEASE_NAME-postgres-ha --gvc GVC_NAME -o yaml. Read the errors with a server-side filter:An SDK gets 401 or 403 from the Client or Frontend API
An SDK gets 401 or 403 from the Client or Frontend API
401 or 403.Cause: The token type does not match the endpoint — a frontend token sent to /api/client, or a backend token sent to /api/frontend — or the environment in the token string is not the one you meant.Fix: Use a backend token for server-side SDKs and a frontend token for browser and mobile SDKs, and create a new one in Admin → API access if needed. See API Tokens.Password-reset or invite links point at the wrong address
Password-reset or invite links point at the wrong address
cpln.local address, or the public address after you made the instance private.Cause: The link base URL is derived when the container starts, from whether publicAccess.enabled is on at that moment.Fix: Restart the workload so the start script derives it again: cpln workload force-redeployment RELEASE_NAME-unleash --gvc GVC_NAME.Render fails with enable exactly one database
Render fails with enable exactly one database
unleash: enable exactly one database — set either postgresHA.enabled or postgres.enabled to true, not both, or the variant naming postgresHA.enabled (production) or postgres.enabled (dev/lightweight).Cause: Both postgresHA.enabled and postgres.enabled are true, or both are false.Fix: Enable exactly one — see Database. To use the single-instance database, set postgresHA.enabled: false together with postgres.enabled: true.Upgrade fails with a key that was REMOVED or RENAMED
Upgrade fails with a key that was REMOVED or RENAMED
helm upgrade stops at render with admin.password was REMOVED in 1.1.0, config.username was REMOVED in postgres 3.4.0, the postgres block was REMOVED in 2.5.0, backup.minio.accessKey and backup.minio.secretKey were REMOVED, resources.cpu was RENAMED to resources.maxCpu, or postgres.credentials was REMOVED.Cause: Your values still carry a key that moved in template versions 1.1.0, 1.2.0, 1.3.0, 1.3.1, 1.4.0 or 1.5.0. The existing release is left untouched and running.Fix: Follow the matching migration note above — Upgrading from 1.0.x, Upgrading from 1.1.0, Upgrading from 1.2.x, Upgrading from 1.3.x or Upgrading from 1.4.0 — keeping the credentials the database already uses in your database credentials secret.Important Notes
- Create the admin secret and the database credentials secret before installing. A missing prerequisite secret does not fail the install — the workload waits on it with zero log lines.
- Rotating the database password needs a forced redeployment — a running workload keeps the values it started with, and the database keeps its password until you change it there; in HA mode a leader switchover comes first. See Rotating the Database Password.
- The admin secret and the API-token seed apply on first boot only. Change the password and manage tokens in the admin UI; editing the secrets later changes nothing, and an upgrade never resets your password.
- Backend tokens must stay secret (server-side SDKs,
/api/client); frontend tokens are safe to embed in browsers (/api/frontend). - Give each release its own database credentials secret — secret names are org-wide.
- The free edition ships two environments (
development,production); SSO, role-based access control, multiple projects, change requests and audit logs need an Unleash Enterprise license and are not available in this template. - Uninstall deletes the database volume sets — all flags, users and tokens. Enable backups if the data matters; the prerequisite secrets you created survive and must be deleted manually.