Reference
Configuration reference
You can look up every setting of the three images, with its default.
Before you start
- You run the images
forgeopslabs/flux-gate-backend,forgeopslabs/flux-gate-edgeandforgeopslabs/flux-gate-ui, for example with the demodocker-compose.demo.yml. - You have the demo
config.demo.toml, or your ownconfig.toml, mounted into the backend.
What you will do
The backend reads a config.toml file and a few environment variables. The edge server and the UI take their settings from environment variables. The sections below list each setting, what it does, and its default. Secrets such as FLUXGATE_ENCRYPTION_KEY are environment variables so that they stay out of the file.
A check mark (✓) after a default means the value was checked in a running v1.2.0 container: from its default file, its startup log, or its behavior. The other defaults are the v1.2.0 defaults from the product's configuration. They were not exercised.
Backend
config.toml
Mount your file at /app/config/config.toml. When the container starts, its entrypoint copies that file to /app/config.toml, and the backend reads the copy. If you mount nothing, the entrypoint copies a built-in default file instead.
volumes:
- ./config.demo.toml:/app/config/config.toml:roThe first three keys are required. Every other key is optional and falls back to its default. Put the keys of a table such as [auth] under that table heading.
| Key | Default | Description |
|---|---|---|
allowed_origin | http://localhost:3000 in config.demo.toml ✓; http://localhost:8090 in the built-in default file | The exact origin of the UI. The backend accepts browser requests from this origin only. Single sign-on callbacks redirect to it. |
http_addr | 0.0.0.0:8080 ✓ | Address and port of the REST server and of Swagger UI at /docs/. |
grpc_addr | 0.0.0.0:50051 ✓ | Address and port of the gRPC server. Edge servers connect here. |
public_base_url | unset | The public address of the backend as browsers and identity providers reach it, for example https://fluxgate.example.com. The backend builds single sign-on callback addresses from it. A trailing slash is removed. When unset, the backend derives the address from each request, and logs a warning at startup. Set it in production. |
grpc_tls_cert_file | unset | PEM certificate chain for the gRPC server. Set it with grpc_tls_key_file, or set neither. When both are set, the gRPC port serves TLS only, and edge servers must use an https:// EDGE_BACKEND_GRPC. |
grpc_tls_key_file | unset | PEM private key for the gRPC server. An unreadable or invalid file stops the backend at startup. |
[auth] access_token_ttl_minutes | 30 ✓ | Lifetime of an access token in minutes. Values below 1 become 1. |
[auth] refresh_token_ttl_days | 7 ✓ | Lifetime of a refresh token in days. Values below 1 become 1. |
[jira] allow_insecure_http | false | Allow http:// Jira base URLs for write-back. Keep it false unless you test against a local Jira. |
[jira] ui_base_url | unset, so allowed_origin is used | The UI address that FluxGate puts in the remote links it creates on Jira tickets. |
[jira] inbound_per_minute | 120 | Sustained number of inbound Jira events per minute for one integration. Excess events get 429. A value of 0 becomes the default. |
[jira] inbound_burst | 60 | Number of inbound Jira events that one integration can send at once. A value of 0 becomes the default. |
[typesafe] base_url | https://api.typesafe.ai ✓ | Address of the TypeSafe API that serves the Jev AI features. |
[typesafe] model | jev-1.13.0 ✓ | The Jev model version. It is pinned on purpose: moving aliases such as jev-latest can change answers. |
[typesafe] timeout_ms | 3000 ✓ | Timeout of each HTTP attempt to the TypeSafe API, in milliseconds. A value of 0 becomes the default. |
[typesafe] max_in_flight | 16 ✓ | Number of TypeSafe requests that can run at the same time. A value of 0 becomes the default. |
The demo config.demo.toml sets only the first three keys. It has public_base_url too, but commented out. These are its settings, with the comments removed:
allowed_origin = "http://localhost:3000"
http_addr = "0.0.0.0:8080"
grpc_addr = "0.0.0.0:50051"
#public_base_url = "https://fluxgate.example.com"To change token lifetimes and the Jev model, add tables to the same file:
[auth]
access_token_ttl_minutes = 15
refresh_token_ttl_days = 14
[typesafe]
model = "jev-1.13.0"
timeout_ms = 5000Environment variables
Environment variables carry the database address and the secrets. The backend does not read other config.toml keys from the environment, so no variable overrides a key in the file.
| Variable | Default | Description |
|---|---|---|
DATABASE_URL | none, required | PostgreSQL connection string, postgres://<user>:<password>@<host>:5432/<database>. URL-encode special characters in the password. The backend runs its migrations against this database at every start. |
FLUXGATE_ENCRYPTION_KEY | none | The key that encrypts the secrets FluxGate stores: Jira write-back tokens and single sign-on client secrets. It must be the standard base64 of exactly 32 bytes. The demo compose file refuses to start without it. |
FLUXGATE_SSO_<SLUG>_CLIENT_SECRET | unset | Optional client secret for one single sign-on provider. It wins over the stored secret and needs no encryption key. Uppercase the provider slug and replace every character that is not a letter or digit with _: the slug my-idp gives FLUXGATE_SSO_MY_IDP_CLIENT_SECRET. |
TYPESAFE_API_KEY | unset | Your TypeSafe API key. When it is set, the Jev AI features turn on. Without it, all AI controls stay hidden. The key is never read from config.toml. |
FEATURE_TOGGLE_CONFIG | unset | Path of a configuration file to load instead of /app/config.toml. You rarely need it, because the entrypoint already copies your mounted file. |
RUST_LOG | info in the demo compose file | Not read. The images set the log level in a bundled logging file. |
Without a valid FLUXGATE_ENCRYPTION_KEY, saving a Jira token or a single sign-on secret fails. Set the key from the first boot.
Edge server
The edge server reads its settings from environment variables. The image has no config.toml, so you must set the first four variables yourself. You can also mount a config.toml and point EDGE_CONFIG_FILE at it. Environment variables override values in that file.
| Variable | Default | Description |
|---|---|---|
EDGE_BACKEND_GRPC | none, required | Address of the backend gRPC server, for example http://backend:50051. |
EDGE_HTTP_ADDR | none, required | Address and port the edge listens on, for example 0.0.0.0:8081. |
EDGE_CLIENT_ID | none, required | The ID (a UUID) of the client the edge authenticates as. It is not the SDK key. |
EDGE_CLIENT_SECRET | none, required | The API key of that client. |
EDGE_NODE_ID | the host name | A stable name for this edge. A relay needs a stable value, because you register the relay by it. |
EDGE_CONFIG_FILE | config.toml | Path of an optional configuration file. If the file does not exist, the edge uses environment variables only. |
The demo compose file starts the edge with empty EDGE_CLIENT_ID and EDGE_CLIENT_SECRET. The edge then cannot authenticate to the backend until you set both.
Tuning settings
Every other edge setting has a default, and you rarely change them. Set one with an EDGE_ variable. A double underscore __ separates the section from the key: EDGE_CACHE__CLIENT_TTL_SECS=60 sets client_ttl_secs in the cache section. A single underscore, as in EDGE_CACHE_CLIENT_TTL_SECS, is ignored. In a config.toml, the same settings sit in the matching table, for example [cache].
| Variable | Default | Description |
|---|---|---|
EDGE_CACHE__MAX_CAPACITY | 10000 ✓ | Number of flags the edge keeps in its cache. The oldest unused flags leave first when the cache is full. |
EDGE_CACHE__CLIENT_TTL_SECS | 300 ✓ | Seconds the edge caches a successful client authentication. A disabled client or a rotated API key can keep working for this long. The edge caches a rejected key for a fixed 30 seconds. |
EDGE_CACHE__CLIENT_MAX_CAPACITY | 1000 ✓ | Number of client credentials whose authentication the edge caches. |
EDGE_GRPC__CONNECT_TIMEOUT_SECS | 5 | Timeout for connecting to the backend. |
EDGE_GRPC__TIMEOUT_SECS | 10 | Timeout of each gRPC request. |
EDGE_GRPC__TCP_KEEPALIVE_SECS | 30 | TCP keepalive interval. |
EDGE_GRPC__HTTP2_KEEPALIVE_SECS | 20 | HTTP/2 keepalive interval. |
EDGE_GRPC__KEEP_ALIVE_WHILE_IDLE | true | Keep the connection alive when no request runs. |
EDGE_GRPC__CONCURRENCY_LIMIT | 256 | Maximum number of concurrent gRPC requests. |
EDGE_GRPC__TCP_NODELAY | true | Turn on TCP_NODELAY for the connection. |
EDGE_GRPC__COMPRESSION | none | Compression of gRPC requests: none or gzip. The older name EDGE_GRPC_COMPRESSION still works, but it is deprecated. |
EDGE_FLUSH__ASSIGNMENT_FLUSH_SECS | 10 ✓ | Seconds between sends of user assignments to the backend. |
EDGE_FLUSH__EVALUATION_FLUSH_SECS | 30 | Seconds between sends of evaluation events to the backend. |
EDGE_FLUSH__EVALUATION_EVENT_QUEUE_CAPACITY | 10000 | Size of the queue of evaluation events that wait to be sent. |
EDGE_FLUSH__ASSIGNMENT_FLUSH_BATCH_SIZE | 1000 | Maximum number of user assignments in one send. |
EDGE_FLUSH__EVALUATION_FLUSH_BATCH_SIZE | 500 | Maximum number of evaluation events in one request. |
EDGE_RETRY__BASE_DELAY_MS | 500 | Base delay of the exponential backoff between retries, in milliseconds. |
EDGE_RETRY__MAX_ATTEMPTS | 3 | Maximum number of attempts for a direct gRPC call. |
EDGE_RETRY__STREAM_INITIAL_DELAY_SECS | 1 | First delay before the edge reconnects the flag stream. |
EDGE_RETRY__STREAM_MAX_DELAY_SECS | 30 | Longest delay between reconnect attempts. |
EDGE_GRPC__TLS_CA_FILE | empty | PEM file with the CA that signed the backend gRPC certificate. Used only when EDGE_BACKEND_GRPC starts with https://. Empty trusts the built-in public roots. |
Resilience settings
These settings keep an edge serving when the backend is unreachable. See Edge resilience for how they fit together.
| Variable | Default | Description |
|---|---|---|
EDGE_RESILIENCE__CLIENT_STALE_IF_ERROR_SECS | 86400 | Seconds after its last successful check that the edge still accepts an SDK key while the backend is unavailable. 0 turns it off. |
EDGE_RESILIENCE__READY_MAX_AGE_SECS | 0 | Config age in seconds above which /health and /health/ready return 503. 0 turns the limit off. |
EDGE_SNAPSHOT__DIR | empty | Folder for the local snapshot file. The edge reads it at startup. Empty turns the local snapshot off. |
EDGE_SNAPSHOT__WRITE_INTERVAL_SECS | 30 | Longest wait between two writes of the file after stream updates. |
EDGE_SNAPSHOT__BOOTSTRAP | empty | Where the edge reads a signed bootstrap snapshot: a file path or an https:// URL. Empty turns it off. Needs EDGE_SNAPSHOT__TRUSTED_KEYS. Enterprise: the backend needs a signing key. |
EDGE_SNAPSHOT__TRUSTED_KEYS | empty | Public keys that may sign a bootstrap snapshot, as one comma-separated string of <key ID>:<public key>. In config.toml, use a list. |
EDGE_SNAPSHOT__STARTUP_WAIT_SECS | 5 | Seconds the stream gets to deliver flags before the edge reads the bootstrap snapshot. |
EDGE_SNAPSHOT__MAX_AGE_SECS | 0 | Oldest bootstrap snapshot the edge accepts, in seconds since the backend generated it. 0 means no limit. |
Relay settings
A relay is an edge that serves other edges. Registering a relay needs the edge_resilience entitlement (Enterprise).
| Variable | Default | Description |
|---|---|---|
EDGE_RELAY__ENABLED | false | Run this edge as a relay. |
EDGE_RELAY__GRPC_ADDR | 0.0.0.0:50061 | Address of the relay gRPC listener. |
EDGE_RELAY__SERVE_HTTP | true | false makes a pure relay that serves only the health, detail, and metrics paths. |
EDGE_RELAY__TLS_CERT_FILE | empty | PEM certificate chain of the relay listener. Set it with the key file, or set neither. |
EDGE_RELAY__TLS_KEY_FILE | empty | PEM private key of the relay listener. |
EDGE_RELAY__ALLOW_INSECURE | false | Serve children over plaintext gRPC when no TLS files are set. Without TLS files and this setting, the edge stops at startup. |
The images set the log level in a bundled logging file. RUST_LOG is not read.
Admin UI
The UI container reads four variables when it starts. It writes them into a small file that the browser loads. The UI has no proxy: your browser calls the backend directly, at <BACKEND_PROTOCOL>://<BACKEND_HOST>:<BACKEND_PORT>/api/v1. Set these variables to the address that your browser uses to reach the backend, not to the compose service name backend.
| Variable | Demo value | Description |
|---|---|---|
BACKEND_HOST | localhost | Host name of the backend as the browser reaches it. |
BACKEND_PORT | 8080 | Port of the backend as the browser reaches it. The port is always part of the address, so use 443 for HTTPS on the default port. |
BACKEND_PROTOCOL | http | http or https. Use https when the UI page is served over HTTPS. |
WS_PROTOCOL | ws | ws or wss, for the live-update connection. Use wss with https. |
The variables have no built-in defaults. If you leave one out, the UI builds an invalid backend address. Set all four.
Ports
| Port | Service | Protocol | Notes |
|---|---|---|---|
3000 | Admin UI | HTTP | Published by the demo compose file. The container listens on port 80 inside. |
8080 | Backend | HTTP | REST API at /api/v1, and Swagger UI at /docs/. Configured by http_addr. |
50051 | Backend | gRPC | Edge servers connect here. Configured by grpc_addr. The demo compose file does not publish it. Never publish it in production. |
8081 | Edge server | HTTP | Flag evaluation for your apps. Configured by EDGE_HTTP_ADDR. |
5433 | PostgreSQL | TCP | Host port in the demo compose file. The container listens on 5432 inside. Remove this mapping in production. |
To move a service to another host port, change the left side of its ports entry in the compose file, for example "3100:80". Then update the settings that point at it: allowed_origin for the UI, and BACKEND_PORT for the backend.
Secrets
| Value | Where | How to create it | What breaks when it changes |
|---|---|---|---|
FLUXGATE_ENCRYPTION_KEY | Backend environment | openssl rand -base64 32 | Stored Jira tokens and single sign-on client secrets stop decrypting. Enter each one again in the UI. Do not change the key while the database exists. Back it up. |
EDGE_CLIENT_SECRET | Edge environment | The API key of a client. Create the client in the UI. | If you regenerate the API key of the client, the edge cannot authenticate until you set the new value. Requests already authenticated in the cache keep working for up to EDGE_CACHE__CLIENT_TTL_SECS. |
EDGE_CLIENT_ID | Edge environment | The ID of the same client. | The edge cannot authenticate when the ID and the secret belong to different clients. |
TYPESAFE_API_KEY | Backend environment | Create it in your TypeSafe account. | Removing it turns the Jev AI features off. |
FLUXGATE_SSO_<SLUG>_CLIENT_SECRET | Backend environment | Copy it from your identity provider. | Set the new value and recreate the backend. |
Database password in DATABASE_URL | Backend environment, and PostgreSQL | Set it when you create the database user. | The backend cannot connect and does not start. |
| JWT signing secrets | The database, managed in the UI | FluxGate creates the first one at first start. Rotate or deactivate secrets in the UI. | After Generate New Secret, the old secret keeps verifying for a grace period equal to the access-token lifetime (30 minutes by default). Deactivate All JWT Secrets signs every user out. |
Keep these values in a secret store, not in the compose file. Never commit the .env file. The demo password local123 in the compose file is for local use only.
Good to know
- A change in
config.tomlneeds a backend restart. The entrypoint copies the file at container start. - Run one backend instance. Scale the edge server for more evaluation traffic.
- Docker Hub publishes the images with the tags
v2.0.1andlatest. Pinv2.0.1in production.
Troubleshooting
Browser requests fail with a CORS error
allowed_origin does not match the address in the browser address bar. Set it to the exact origin of the UI, with scheme and port and no trailing path. Restart the backend.
The backend ignores my config.toml
The file must be mounted at /app/config/config.toml, not at /app/config.toml. The entrypoint prints Using mounted config.toml when it finds the file. If it prints No mounted config found, check the volume path.
Changing RUST_LOG does not change the logs
The images set the log level in a bundled logging file; RUST_LOG is not read.
An EDGE_ setting has no effect
Check the separator. A section setting needs a double underscore: EDGE_GRPC__TIMEOUT_SECS, not EDGE_GRPC_TIMEOUT_SECS.
Next
To call the edge server over HTTP, see the Edge server API. To plan for backend outages, see Edge resilience.