From 413d86cc3cb3165a29aa5d5672af00dd48f86cb2 Mon Sep 17 00:00:00 2001 From: Tudor Date: Sun, 23 Aug 2026 10:58:29 +0100 Subject: [PATCH] chore(flags): wire UNLEASH_URL and the SDK cache volume into the stacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both variables default to empty, so an environment without Unleash has every flag off — the correct dark state rather than a boot failure. The cache volume is the mitigation for the one real regression risk in this design: the SDK evaluates everything False until it syncs, so a backend cold-starting with an empty cache while Unleash is unreachable would make a *released* feature disappear. On a named volume the disk cache survives a restart. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_015mWQnpye9F299NVRCCSRvj --- docker-compose.portainer.staging.yml | 9 +++++++++ docker-compose.portainer.yml | 9 +++++++++ docker-compose.yml | 4 ++++ 3 files changed, 22 insertions(+) diff --git a/docker-compose.portainer.staging.yml b/docker-compose.portainer.staging.yml index d0cff2d..3bbad6b 100644 --- a/docker-compose.portainer.staging.yml +++ b/docker-compose.portainer.staging.yml @@ -16,6 +16,8 @@ # ADMIN_API_KEY — Backend admin API key # TYPESENSE_API_KEY — Typesense admin API key # TYPESENSE_SEARCH_KEY — Typesense search-only key (exposed to frontend) +# UNLEASH_URL — http://:4242/api (empty = all flags off) +# UNLEASH_API_TOKEN — Unleash *client* token, environment: development # AIRFLOW_ADMIN_USER — Airflow admin username (password auto-generated, see api-server logs) # STAGING_DB_IP — macvlan IP for staging Postgres (default 10.0.1.190) # STAGING_FRONTEND_IP — macvlan IP for staging frontend (default 10.0.1.151) @@ -55,6 +57,12 @@ services: ADMIN_API_KEY: ${ADMIN_API_KEY:-changeme} TYPESENSE_URL: http://typesense:8108 TYPESENSE_API_KEY: ${TYPESENSE_API_KEY:-changeme} + # Unset means every feature flag is False — the correct dark state for an + # environment with no Unleash, not a failure. + UNLEASH_URL: ${UNLEASH_URL:-} + UNLEASH_API_TOKEN: ${UNLEASH_API_TOKEN:-} + volumes: + - unleash_cache:/app/.unleash depends_on: sc_database: condition: service_healthy @@ -212,3 +220,4 @@ volumes: postgres_data: typesense_data: airflow_logs: + unleash_cache: diff --git a/docker-compose.portainer.yml b/docker-compose.portainer.yml index a593d80..e44a9b6 100644 --- a/docker-compose.portainer.yml +++ b/docker-compose.portainer.yml @@ -7,6 +7,8 @@ # ADMIN_API_KEY — Backend admin API key # TYPESENSE_API_KEY — Typesense admin API key # TYPESENSE_SEARCH_KEY — Typesense search-only key (exposed to frontend) +# UNLEASH_URL — http://:4242/api (empty = all flags off) +# UNLEASH_API_TOKEN — Unleash *client* token, environment: production # AIRFLOW_ADMIN_USER — Airflow admin username (password auto-generated, see api-server logs) services: @@ -44,6 +46,12 @@ services: ADMIN_API_KEY: ${ADMIN_API_KEY:-changeme} TYPESENSE_URL: http://typesense:8108 TYPESENSE_API_KEY: ${TYPESENSE_API_KEY:-changeme} + # Unset means every feature flag is False — the correct dark state for an + # environment with no Unleash, not a failure. + UNLEASH_URL: ${UNLEASH_URL:-} + UNLEASH_API_TOKEN: ${UNLEASH_API_TOKEN:-} + volumes: + - unleash_cache:/app/.unleash depends_on: sc_database: condition: service_healthy @@ -201,3 +209,4 @@ volumes: postgres_data: typesense_data: airflow_logs: + unleash_cache: diff --git a/docker-compose.yml b/docker-compose.yml index f72bb7a..b3fdd41 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -36,6 +36,10 @@ services: ADMIN_API_KEY: ${ADMIN_API_KEY:-changeme} TYPESENSE_URL: http://typesense:8108 TYPESENSE_API_KEY: ${TYPESENSE_API_KEY:-changeme} + # Unset means every feature flag is False — the correct dark state for an + # environment with no Unleash, not a failure. + UNLEASH_URL: ${UNLEASH_URL:-} + UNLEASH_API_TOKEN: ${UNLEASH_API_TOKEN:-} volumes: - ./data:/app/data:ro depends_on: