Feature flags are how grown-up teams ship: merge code dark, roll it out to 5% of users, watch the metrics, and flip a kill switch instantly if something's on fire — no redeploy, no rollback drama at 3am. Unleash (https://www.getunleash.io) is a mature open-source feature-flag platform with gradual rollouts, user targeting, strategies, and an audit log. This guide self-hosts the Unleash server on PandaStack backed by managed PostgreSQL.
Why self-host Unleash
- Your flags, your data — flag evaluations and user context stay on infrastructure you control.
- No per-seat SaaS pricing — the open-source server is free; you pay only for the compute and database.
- Full feature set — gradual rollout, targeting by user/segment, and kill switches are all in the open-source core.
If you want zero ops, hosted feature-flag SaaS exists — but self-hosting Unleash is genuinely light: it's one server plus a Postgres database.
Step 1: Create the PostgreSQL database
Unleash stores everything — flags, strategies, audit history — in PostgreSQL. Dashboard (https://dashboard.pandastack.io) → Databases → New Database → PostgreSQL. Copy the connection string.
Step 2: Dockerfile
The official image is unleashorg/unleash-server. A thin wrapper keeps config explicit:
FROM unleashorg/unleash-server:latest
EXPOSE 4242
# DATABASE_URL and secrets come from PandaStack env vars at runtimeUnleash reads its Postgres connection from DATABASE_URL and needs SSL awareness for a managed database.
Step 3: Deploy the server
- 1Push the repo (or just point at the image) to GitHub / the dashboard.
- 2New App → Container App, container port 4242.
- 3Environment variables:
| Variable | Value |
|---|---|
DATABASE_URL | your managed Postgres connection string |
DATABASE_SSL | true |
INIT_ADMIN_API_TOKENS | a bootstrap admin token (see below) |
- 1Deploy. Unleash runs its own schema migrations on first boot against your Postgres.
The admin UI is now at https://your-unleash.pandastack.io. The default first-run credentials are admin / unleash4all — change that password immediately, because an open Unleash instance with default creds lets anyone flip your production flags.
CLI path for the whole thing:
npm install -g @pandastack/cli
panda login
panda deployStep 4: Create a feature flag
In the UI:
- 1Create feature toggle → name it, e.g.
new-checkout. - 2Add an activation strategy. Start with Gradual rollout at 5%.
- 3Optionally add constraints — only users in the
betasegment, only in the EU, etc. - 4Save. The flag is off for 95% of users and on for 5%, deterministically per user.
Step 5: Generate an SDK token
Your app authenticates to Unleash with a client token (read-only, safe to embed in backend services), distinct from the admin token:
- API access → New API token → Client. Copy it.
Store it as a PandaStack env var in your application, UNLEASH_API_TOKEN.
Step 6: Evaluate flags in your app
Node backend with the official SDK:
import { initialize } from 'unleash-client'
const unleash = initialize({
url: 'https://your-unleash.pandastack.io/api/',
appName: 'my-app',
customHeaders: { Authorization: process.env.UNLEASH_API_TOKEN },
})
unleash.on('ready', () => {
const enabled = unleash.isEnabled('new-checkout', {
userId: currentUser.id, // context for targeting + consistent bucketing
})
if (enabled) renderNewCheckout()
else renderOldCheckout()
})The SDK polls Unleash and caches flag definitions locally, so isEnabled() is an in-memory check — it does not make a network call per evaluation, and it keeps working even if the Unleash server briefly hiccups.
Step 7: Frontend flags safely
For browser/SPA flags, use the Unleash Proxy or the front-end API rather than embedding a client token in browser JS (which anyone can read). The proxy evaluates flags server-side and exposes only the results to the browser. Run the proxy as another small PandaStack container app pointing at your Unleash server.
Step 8: The kill switch drill
The whole point of flags is the emergency off switch. Practice it: with new-checkout at 100%, toggle it off in the UI. Within the SDK's refresh interval (seconds), every app instance stops serving the new checkout — no deploy, no rollback, no incident bridge. Knowing this works before you need it is worth the five-minute test.
Step 9: Operational notes
- Backups — all flag state is in Postgres; PandaStack managed backups cover it.
- Audit log — Unleash records who changed which flag when. Keep it; it answers "who turned that on?" instantly.
- Rotate the admin token and delete the default admin password on day one.
- Overkill check — if you have literally two flags and one developer, an env-var boolean and a redeploy might be enough. Unleash pays off when you want gradual rollouts, targeting, and instant kill switches without shipping code.
Wrap-up
Unleash gives you real feature-flag superpowers — gradual rollouts, targeting, instant kill switches — self-hosted on your own infrastructure. On PandaStack it's a single container app plus a managed Postgres database, with SDKs for every major language. Change that default password. Docs: https://docs.pandastack.io. Start free at https://dashboard.pandastack.io.