Developer guide
Developer guide
You can go from an empty folder to a first flag evaluation by copying commands from one page.
This page is a runbook. Run the sections in order. Each section ends with a check that you can run, and a link to the chapter page that explains the topic in depth. The page uses the same two files as the video series, so each chapter picks up where this page ends.
Prerequisites
- Docker with Compose v2 (
docker compose versionworks). openssl, to generate a secret.curlandjq, for the checks.- Node 20 or newer, only for the OpenFeature example in section 7.
- Free ports 3000 (UI), 8080 (backend), 8081 (edge server) and 5433 (PostgreSQL).
The images come from Docker Hub: forgeopslabs/flux-gate-backend, forgeopslabs/flux-gate-ui and forgeopslabs/flux-gate-edge, tag v2.0.1. You do not need a source checkout.
1. Get the files
Create an empty folder and download the two demo files into it:
mkdir fluxgate && cd fluxgate
curl -fsSLO https://flux.forgeopslabs.com/downloads/docker-compose.demo.yml
curl -fsSLO https://flux.forgeopslabs.com/downloads/config.demo.tomlCheck that both files are there:
lsThe output lists config.demo.toml and docker-compose.demo.yml.
Learn more: Install and first boot describes what the two files contain.
2. Create the encryption key
FluxGate encrypts the secrets it stores with one key. Generate it once and keep it in a .env file next to the compose file:
echo "FLUXGATE_ENCRYPTION_KEY=$(openssl rand -base64 32)" > .envCheck that the file holds one line:
wc -l .envLearn more: Install and first boot.
3. Start FluxGate
docker compose -f docker-compose.demo.yml up -dCompose starts PostgreSQL, the backend and the UI. The backend runs its database migrations at startup. Check the containers, then ask the backend for its API documentation page. Type the trailing slash:
docker compose -f docker-compose.demo.yml ps
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8080/docs/All three services show Up, and the curl command prints 200. If the curl command fails to connect, wait a few seconds and run it again.
Learn more: Install and first boot has the expected ps output and fixes for common start problems.
4. Create the first admin
- Open
http://localhost:3000. On a fresh database FluxGate redirects you to/create-admin. - Fill Username with
admin, then Password, Confirm Password, First Name, Last Name and Email. Click Create Admin. - On Sign in to FluxGate, sign in with the new credentials.
You land on System Overview at /. Check it from the terminal: the backend now refuses unauthenticated calls.
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8080/api/v1/teamsThe command prints 401.
Learn more: Install and first boot.
5. Create a team, an environment, and a flag
FluxGate needs two people to deploy a stage: one who requests the deployment and a different one who approves it. Nobody approves their own request. The shortest path is therefore: you (admin) request, and a second user, sam, approves. The steps below take one flag, express-checkout, from nothing to a deployed Development stage.
Sign in as admin and work through these steps in order.
- Create the team. Open Teams under Settings to reach
/settings/teams, then click Create New Team. EnterCheckoutas Team Name andJuniper Market checkout squadas Description, and click Create Team. Reload the page. Check that Select team in the header shows Checkout. If it does not, open Select team and choose Checkout. - Create the environment. Click Environments under Build, then Create New Environment. Enter
Developmentas Environment Name, leave Environment Type onDevelopment, and click Create Environment. The toast "Environment created successfully" appears. - Create the approver. Open Users under Settings and click Create New User. Enter
samas Username, choose a Password, add a first name, a last name and an email, and click Create User. On the Assign Teams tab, tick Checkout and click Assign Selected Teams. On the Assign Roles tab, tick Approver and click Assign Selected Roles. - Give yourself the Requester role. In the Users list, click the pencil icon in the
adminrow, go to the Assign Roles tab, tick Requester, and click Assign Selected Roles. Then open the avatar menu, click Log out, and sign in asadminagain. The UI reads your roles when you sign in, so the new role takes effect only after that. - Create the approval policy. Click Approval Policies under Govern and click Create Policy. Enter
Release approvalsas Policy Name. Leave Scope on All Environments. Open Approver Roles, chooseApprover, and click the dialog heading to close the list. Click Create Policy. The toast "Approval policy created successfully" appears. - Create the flag. Click Features under Build, then Create New Feature. Enter
express-checkoutas Name, and set Feature Type toCONTEXTUAL. In Feature Variants, click Add Variant twice and fill the two rows: Variant Keyclassicwith Valueclassic, and Variant Keyexpresswith Valueexpress. - Add a stage. Scroll to Rollout Templates. The template Simple on/off (system) and the environment Development are already selected. Click Preview, then Apply Template. The toast "Rollout template applied" appears and the stage graph shows one stage, Development. Click Create Feature. FluxGate opens Edit Feature with the toast "Feature created successfully". The flag stays in the lifecycle
DRAFT. That is fine: the lifecycle does not block a deployment. - Serve a variant. Click the edge of the Development node in the stage graph (not its name) to select it. In Stage Editor, click Add Criterion and then Expand. Under Variant Selection Mode, choose Specific Variant and pick
expressunder "Select the variant to return:". Click Save Stage Criteria. A criterion without rules matches every request, so this stage now servesexpressto everyone. - Request the deployment. With Development still selected, open Actions and click Request Deployment. The stage status changes to
DEPLOYMENT_REQUESTED. - Approve as
sam. Log out and sign in assam. FluxGate opens Update Your Password on the first sign-in: enter the password you set in step 3, a new password twice, and click Update Password. Sign in again assam. Click Approvals under Govern. The pending request reads "Stage NOT_DEPLOYED -> DEPLOYMENT_REQUESTED for feature express-checkout". Click Approve. The toast "Approval recorded" appears. - Deploy. Still as
sam, openexpress-checkoutfrom Features, click Edit, select the Development stage, open Actions, and click Deploy. The stage status changes toDEPLOYED.
Check the result in the UI: open Features, click the details button of express-checkout, and open the Stages tab. The Development stage shows DEPLOYED. Section 7 checks it from the command line.
Learn more: Teams, users and roles, Environments and pipelines, Create your first feature, Targeting rules and Approvals and policies. The chapters build the full setup with a checkout-release pipeline (Development, Staging, Production) and the users priya and sam.
6. Create a client and start the edge server
An app never calls the backend to evaluate a flag. It calls the edge server, which keeps a cached copy of your flags. The edge server signs in to the backend as a client, so you create that client first.
-
Click Clients under Connect, then Create New Client.
-
Enter
checkout-serviceas Client Name, chooseBackendas Client Type, and chooseDevelopmentas Environment. The environment decides which stage configuration the client sees. Click Create Client. -
The page Edit Client opens. It shows API Key and SDK key, both masked. Click the copy button next to API Key and keep the key. The client ID is the ID in the page address (
/clients/<client ID>/edit); the Client ID column on/clientshas a copy button as well. -
Append both values to
.env, start the edge server, and check its health:bashecho EDGE_CLIENT_ID=<checkout-service client ID> >> .env echo EDGE_CLIENT_SECRET=<checkout-service API key> >> .env docker compose -f docker-compose.demo.yml --profile edge up -d edge curl -s -o /dev/null -w '%{http_code}\n' http://localhost:8081/health
The health check prints 200 when the edge server has connected to the backend. A 503 right after the start is normal for about a second: run the check again. If the 503 persists, the two values in .env are wrong. Run docker compose -f docker-compose.demo.yml logs edge and look for invalid client_secret.
Learn more: Clients and edge server also creates a Web client and explains which endpoint accepts which credential.
7. Evaluate a flag
Evaluate express-checkout as a user in Canada on the plus tier. Every request carries a bucketing key (bucketingKey or targetingKey), which FluxGate uses to place a user in a percentage rollout. This guide's flag serves express to everyone, and a rollout split would use the key.
The two OFREP-based tabs authenticate with an SDK key: the client ID, a dot, and the API key. Build it from .env:
export FLUXGATE_SDK_KEY="$(grep ^EDGE_CLIENT_ID= .env | cut -d= -f2-).$(grep ^EDGE_CLIENT_SECRET= .env | cut -d= -f2-)"curl -s -X POST http://localhost:8081/evaluate \
-H 'Content-Type: application/json' \
-d '{"flagKey":"express-checkout","context":{"bucketingKey":"user-1","country":"CA","user_tier":"plus"}}' | jqcurl -si -X POST http://localhost:8081/ofrep/v1/evaluate/flags \
-H "Authorization: Bearer $FLUXGATE_SDK_KEY" \
-H 'Content-Type: application/json' \
-d '{"context":{"targetingKey":"user-1","country":"CA","user_tier":"plus"}}'import { OpenFeature } from '@openfeature/server-sdk';
import { OFREPProvider } from '@openfeature/ofrep-provider';
await OpenFeature.setProviderAndWait(new OFREPProvider({
baseUrl: 'http://localhost:8081',
headers: [['Authorization', `Bearer ${process.env.FLUXGATE_SDK_KEY}`]],
}));
const client = OpenFeature.getClient();
const variant = await client.getStringValue('express-checkout', 'classic', {
targetingKey: 'user-1',
country: 'CA',
user_tier: 'plus',
});
console.log(`checkout: ${variant}`);
await OpenFeature.close();The first call answers as the edge server's own client and takes no credentials. Keep port 8081 private. The OFREP call authenticates the caller by SDK key and evaluates in the environment of the caller's client.
Expected response of /evaluate:
{
"flagKey": "express-checkout",
"value": "express",
"variant": "express",
"reason": "TARGETING_MATCH"
}Expected response of the OFREP call. The etag value differs on your stack:
HTTP/1.1 200 OK
content-length: 193
etag: <etag value>
content-type: application/json
{"flags":[{"key":"express-checkout","value":"express","reason":"TARGETING_MATCH","variant":"express"}],"metadata":{"version":"<etag value>"}}Repeat the OFREP call with the ETag in an If-None-Match header. While the flags and the context are unchanged, the edge server answers 304 Not Modified with no body:
curl -si -X POST http://localhost:8081/ofrep/v1/evaluate/flags \
-H "Authorization: Bearer $FLUXGATE_SDK_KEY" \
-H 'If-None-Match: <etag value from the first response>' \
-H 'Content-Type: application/json' \
-d '{"context":{"targetingKey":"user-1","country":"CA","user_tier":"plus"}}'HTTP/1.1 304 Not Modified
etag: <etag value>To run the OpenFeature example, save the file as app.mjs in a new folder, then run it with Node 20 or newer. The same terminal needs FLUXGATE_SDK_KEY, so run the export command again if you opened a new one:
npm install @openfeature/server-sdk @openfeature/ofrep-provider
node app.mjscheckout: expressLearn more: Clients and edge server and Edge server API.
8. Optional: AI assistance, Jira, single sign-on
These features need no change to the files you already have. Add the setting to .env and restart only the backend.
echo TYPESAFE_API_KEY=<your TypeSafe API key> >> .env
docker compose -f docker-compose.demo.yml up -d backend- Jev AI assistance explains what the key enables.
- Jira setup connects a Jira project, and Jira end to end follows one ticket through a release.
- Single sign-on lets people sign in with an OpenID Connect provider.
Check the restart. The backend shows Up:
docker compose -f docker-compose.demo.yml ps backendThen sign in as admin, select the team, and open AI assistance under Settings (/settings/ai). The page lists the four AI switches, such as Approval risk triage. The AI features stay hidden in the UI until the backend has the key and a team switch is on.
9. Before production
The demo stack is built for a laptop. Before you run FluxGate for a team, work through Going to production. In short:
- Keep
FLUXGATE_ENCRYPTION_KEYin a secret store and back it up. Losing it loses every stored secret. - Replace the demo database password and back up the database volume.
- Put the UI and the backend behind HTTPS, and set
allowed_originandpublic_base_urlto the public addresses. - Keep port 8081 private.
POST /evaluateon the edge server takes no credentials. - Create an approval policy and give each person only the roles they need.
Reset or remove
Stop the stack and keep your data. The next up -d brings your data back; add --profile edge to start the edge server too. The edge server sits behind a Compose profile, so down stops it only when you name the profile. Always add --profile edge. The option does nothing if you never started the edge server:
docker compose -f docker-compose.demo.yml --profile edge downNext
Follow the chapters in order, starting with What is FluxGate.