Skip to content

local: fix dashboard origin to the external UI (http://localhost:3000)#3230

Open
jgraettinger wants to merge 1 commit into
masterfrom
johnny/dashboard-origin-localhost-3000-675537
Open

local: fix dashboard origin to the external UI (http://localhost:3000)#3230
jgraettinger wants to merge 1 commit into
masterfrom
johnny/dashboard-origin-localhost-3000-675537

Conversation

@jgraettinger

Copy link
Copy Markdown
Member

Problem

The multi-stack local refactor set the dashboard origin to a per-stack base+5 (FLOW_PORT_DASHBOARD, e.g. 10005). But nothing binds or serves base+5 — the estuary/ui dev-server runs off-stack on the developer's laptop at http://localhost:3000 and reaches a stack (local or remote) through mise run vm:port-forward. So every consumer of that origin pointed at a dead port:

  • CORS allow-origins on broker / reactor / agent were http://localhost:<base+5>, but the browser's Origin is http://localhost:3000. Gazette's check is an exact string match, and an SSH -L forward can't rewrite the Origin header — so every cross-origin fetch from the UI (journal reads, shard listings) was rejected.
  • Supabase site_url, the flowctl profile dashboard_url, and the reactor's FLOW_DASHBOARD also pointed at base+5, so auth redirects and flowctl auth login's browser-open landed on a dead page.

Change

Introduce one global, deliberately not stack-scoped FLOW_DASHBOARD_ORIGIN="http://localhost:3000" (in stack-env, like cockpit :9090) and route every consumer through it: FLOW_SITE_URL, broker/reactor/agent CORS, reactor FLOW_DASHBOARD, the flowctl dashboard_url, and temp-data-plane's --flow.dashboard / --consumer.allow-origin.

Optional multi-stack UI escape hatch (included)

The per-stack base+5 origin is kept as a second CORS allow-origin on brokers/reactors/agent, so you can run a second UI against a second stack concurrently (convention: that stack's base+5). Because gazette's ALLOW_ORIGIN env vars are single-valued (no env-delim upstream), the two origins are passed as repeated --*.allow-origin flags in the unit ExecStart rather than via the EnvironmentFile.

Known limitation (documented in local/README.md): Supabase site_url is single-valued and stays :3000, so a base+5 UI's auth redirect still lands on :3000 — log in via the :3000 UI. Acceptable for this power-user path.

Verification

Booted a full local stack and ran a live CORS smoke test (preflight OPTIONS) against broker, reactor, and agent:

Origin broker reactor agent
http://localhost:3000 (global UI) reflected reflected reflected
http://localhost:12005 (base+5 escape hatch) reflected reflected reflected
bogus rejected (no ACAO) rejected rejected

Also confirmed: generated env files carry the new origins (no *_ALLOW_ORIGIN lines), running units' ExecStart carry both flags, flowctl dashboard_url = http://localhost:3000/, and Supabase GOTRUE_SITE_URL=http://localhost:3000 in the running auth container. go vet / gofmt clean; no pgTAP tests assert site_url. Additionally verified working with a real UI on the host over vm:port-forward.

The multi-stack refactor set the dashboard origin to a per-stack base+5
(FLOW_PORT_DASHBOARD), but nothing binds or serves base+5 — the estuary/ui
dev-server runs off-stack on the laptop at :3000 and reaches a stack through
`vm:port-forward`. So every consumer of that origin pointed at a dead port:
CORS allow-origins (gazette's check is an exact string match, and an SSH -L
forward can't rewrite the Origin header), Supabase site_url, the flowctl
dashboard_url, and the reactor's FLOW_DASHBOARD.

Introduce one global FLOW_DASHBOARD_ORIGIN=http://localhost:3000 (in stack-env,
deliberately not stack-scoped, like cockpit :9090) and route all consumers
through it: FLOW_SITE_URL, broker/reactor/agent CORS, reactor FLOW_DASHBOARD,
the flowctl profile dashboard_url, and temp-data-plane's --flow.dashboard /
--consumer.allow-origin.

Includes the optional multi-stack UI escape hatch: the per-stack base+5 origin
is kept as a SECOND CORS allow-origin on brokers/reactors/agent, so you can run
a second UI against a second stack. Because gazette's ALLOW_ORIGIN env vars are
single-valued, the two origins are passed as repeated --*.allow-origin flags in
the unit ExecStart rather than via the EnvironmentFile. Known limitation
(documented in local/README.md): site_url is single-valued and stays :3000, so
a base+5 UI's Supabase auth redirect still lands on :3000.
@jgraettinger
jgraettinger force-pushed the johnny/dashboard-origin-localhost-3000-675537 branch from 2fa4632 to 15ba761 Compare July 22, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant