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
One secret must exist before you install, and a second is optional. 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.Choose the database password
postgres.credentials.username, postgres.credentials.password and postgres.credentials.database into a dictionary secret it creates, and the database reads that secret. Nothing to create — but the password ships as the placeholder change-me-unleash-db-password, so set postgres.credentials.password to a value of your own before installing. This applies in both database modes, even with postgres.enabled: false.Installation
Once the admin secret exists, install the template into your GVC, naming the secret and replacing the database password placeholder:--set apiTokens.secretName=API_TOKENS_SECRET_NAME if you created the optional token seed. Prefer a values file (--values) over --set for the database password if you do not want it in your shell history. If you run more than one release of this template in the same org, also give each its own postgresHA.config.credentialsSecretName (or postgres.config.credentialsSecretName in single-instance mode) — 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.postgres.credentials.* — the chart writes them into the dictionary secret named by postgresHA.config.credentialsSecretName or postgres.config.credentialsSecretName (whichever database is enabled), and the database reads that secret. Change postgres.credentials.password before installing even when postgres.enabled is false. 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 a second release of this template left on the default credentialsSecretName is refused at install with cannot be updated because it is being managed by a different release and creates nothing — the first release is unaffected. Give each release its own name.
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. Unleash absorbed that change — the chart now creates the credentials secret itself — so there is no new prerequisite, only a rename of three keys in single-instance mode:
config.username was REMOVED in postgres 3.4.0), which tells you to create a dictionary secret yourself — ignore that advice here; this template creates it from postgres.credentials.*. 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 same postgres.credentials.* block as the single-instance ones, and the chart creates the secret named by postgresHA.config.credentialsSecretName.
postgres.credentials.* — the running cluster was initialized with them — and delete the postgresHA.postgres block entirely. Leaving postgres.enabled: false is correct; the postgres.credentials.* values feed both database modes. 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.
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, 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.A second release is refused because a resource is managed by a different release
A second release is refused because a resource is managed by a different release
cannot be updated because it is being managed by a different release, naming the database credentials secret, and creates nothing.Cause: Secret names are org-wide, and both releases are trying to create the same credentialsSecretName (default my-unleash-db-credentials). The first release owns it.Fix: Give the new release its own postgresHA.config.credentialsSecretName (or postgres.config.credentialsSecretName in single-instance mode) and install again. The first release is unaffected.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, or resources.cpu was RENAMED to resources.maxCpu.Cause: Your values still carry a key that moved in template versions 1.1.0, 1.2.0, 1.3.0, 1.3.1 or 1.4.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 or Upgrading from 1.3.x — keeping the credentials the database already uses. Do not create a database credentials secret yourself; this template creates it.Important Notes
- Create the admin secret before installing, and change
postgres.credentials.passwordfrom itschange-meplaceholder. A missing prerequisite secret does not fail the install — the workload waits on it with zero log lines. - 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
credentialsSecretName— secret names are org-wide, and a second release on the default name is refused at install. - 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.