Skip to main content

Offline Mode (Air-Gapped)

Some environments block all outbound internet traffic — regulated enclaves, government clouds, disconnected networks. Offline mode lets those deployments keep using feature flags with no changes to application code: your services talk to a small in-cluster relay instead of the hosted FlagTGL control plane, and that relay serves flags from a local file you manage from the command line.

Switching between hosted and offline is only the value of one SDK setting — relayProxyUrl. Nothing else in your application changes.

ModerelayProxyUrl
Hostedhttps://flagtgl.com (or your FlagTGL host)
Offlinehttp://flag-file-relay.<namespace>.svc.cluster.local:8080
note

Offline mode is free and intentionally lightweight — it covers flag delivery, not the hosted control plane. Runtime targeting, guarded rollouts, approvals, and evaluation analytics remain part of FlagTGL.

How it works

Every FlagTGL and LaunchDarkly server SDK supports a relay proxy URL. Point it at flag-file-relay — a small container that implements the same relay endpoints (GET /all streaming, GET /sdk/latest-all polling, POST /bulk events) and reads flags from a YAML file. The SDK cannot tell the difference between the relay and the hosted service.

your service ──(relayProxyUrl)──▶ flag-file-relay ──▶ flags.yaml (ConfigMap)
(SDK, unchanged) (in-cluster) (you edit this)

1. Install the relay

The image is public and self-contained:

docker pull docker.io/anchoo2kewl/flag-file-relay:v0.1.0

Install with Helm when a registry is reachable:

helm install ffr ./chart -n <namespace>

Fully air-gapped install

On a machine with internet access, build a self-contained bundle and copy it in:

./offline/bundle.sh # produces flag-file-relay-offline.tgz
scp flag-file-relay-offline.tgz user@host:

On a host with cluster access:

tar xzf flag-file-relay-offline.tgz && cd flag-file-relay-offline
./install.sh --registry <your-private-registry>

The bundle contains the image, manifests, and installer, so nothing is ever pulled from the internet at run time.

2. Manage flags from the command line

Flags live in a ConfigMap and are edited with the flagctl helper — there is no separate UI to run offline:

flagctl list # all flags and values
flagctl get new-rbac # one flag
flagctl set new-rbac true # global default
flagctl set new-rbac true --tenant acme.example.com # per-tenant override
flagctl set new-rbac false --user [email protected] # per-user override

Changes hot-reload within about a minute — no restart and no SDK reconnect.

File format

flags:
new-rbac:
value: false # default when no override matches
tenants: # optional per-tenant overrides
prod.acme.com: true
new-alerts: false # shorthand: a bare value is the default
max-report-schedules:
value: 15 # numbers and strings are supported
FieldMeaning
valueDefault returned when no override matches.
tenantsMap of tenant key to value, matched against the SDK's tenant context.
usersMap of user key to value, matched against the SDK's user context.

3. Point your services at the relay

Set the relay proxy URL to the in-cluster service. For the FlagTGL and LaunchDarkly server SDKs this is a single field:

launchDarklyClient:
sdkKey: offline # any value; the relay is in-cluster
relayProxyUrl: http://flag-file-relay.blues.svc.cluster.local:8080

To return to hosted mode later, set relayProxyUrl back to your FlagTGL host and roll the services. No code change is required.

Verify

A correctly wired service loads its flags on startup and logs a successful data-source event, with no initialization errors. You can also query the relay directly:

kubectl -n <namespace> exec deploy/flag-file-relay -- flag-file-relay list
kubectl -n <namespace> exec deploy/flag-file-relay -- wget -qO- http://localhost:8080/sdk/latest-all

Capabilities

CapabilityOffline
Boolean, string, and number flagsYes
Per-tenant and per-user overridesYes
Hot reload without restartYes
Percentage rollouts, complex rules, segmentsEdit the file directly
Runtime evaluation analytics and context insightsHosted FlagTGL

When connectivity returns, switch relayProxyUrl back and your existing SDK setup resumes streaming from FlagTGL with full analytics — no migration required.