Skip to content

Add rotom-ng-ui, a web UI fronting several rotom-ng instances - #8

Open
comstud wants to merge 1 commit into
mainfrom
comstud/ui-multi-server
Open

Add rotom-ng-ui, a web UI fronting several rotom-ng instances#8
comstud wants to merge 1 commit into
mainfrom
comstud/ui-multi-server

Conversation

@comstud

@comstud comstud commented Aug 30, 2026

Copy link
Copy Markdown
Collaborator

Operating more than one rotom-ng meant a browser tab per instance. The new rotom-ng-ui binary serves one UI for all of them, proxying every API call to whichever instance the operator has selected.

It embeds the same UI bundle rotom-ng does. There is one UI, not two: it detects which kind of server answered by looking for an "instances" key in /api/config, which this service always sends -- an empty list when none are configured -- and rotom-ng never does.

Configuration mirrors rotom-ng's [http_listener], plus [[instances]] entries of base_url and api_secret. http_listener.secret guards the admin UI; each instance's api_secret authenticates us to that instance.

An instance's base_url is its identity. Names come from the instance's own config, may be empty, and can repeat between servers; base URLs cannot, so that is what the UI stores and sends back, and what an unnamed instance is labelled with. X-Rotom-Instance carries the selection; an absent header selects the first reachable instance.

A monitor polls each instance's /api/config. That one call establishes whether the instance is up, what it calls itself, and its configuration. Carrying the last through is what keeps per-instance features honest: the Jobs tab and worker-stats gating read the selected instance's config, so switching instances changes what the UI offers.

Everything under /api this service does not serve itself is proxied, so a new rotom-ng endpoint works here with no change. Proxied requests are stripped of this service's own credentials before the instance's secret is injected. Failures are distinguished: 404 for an unconfigured instance, 502 for one that did not answer, 503 for none reachable.

The selection persists across visits and survives its instance going down: the page reports that instance as unreachable rather than moving the operator to a different server.

rotom-ng gains http_listener.disable_ui, which withholds its own web UI so a listener fronted by this service need not expose a browser surface. Applied per request, so a config reload turns it on and off.

Both binaries build from one multi-target Dockerfile and publish as images from the same commit. Note the naming: apps/rotom-ng-ui/ is the React app, so the Go service lives in apps/rotom-ng-ui-server/ and builds a binary named rotom-ng-ui; "make rotom-ng-ui" builds that binary and "make ui" builds the React bundle.

Operating more than one rotom-ng meant a browser tab per instance. The
new rotom-ng-ui binary serves one UI for all of them, proxying every API
call to whichever instance the operator has selected.

It embeds the same UI bundle rotom-ng does. There is one UI, not two: it
detects which kind of server answered by looking for an "instances" key
in /api/config, which this service always sends -- an empty list when
none are configured -- and rotom-ng never does.

Configuration mirrors rotom-ng's [http_listener], plus [[instances]]
entries of base_url and api_secret. http_listener.secret guards the admin
UI; each instance's api_secret authenticates us to that instance.

An instance's base_url is its identity. Names come from the instance's
own config, may be empty, and can repeat between servers; base URLs
cannot, so that is what the UI stores and sends back, and what an unnamed
instance is labelled with. X-Rotom-Instance carries the selection; an
absent header selects the first reachable instance.

A monitor polls each instance's /api/config. That one call establishes
whether the instance is up, what it calls itself, and its configuration.
Carrying the last through is what keeps per-instance features honest: the
Jobs tab and worker-stats gating read the selected instance's config, so
switching instances changes what the UI offers.

Everything under /api this service does not serve itself is proxied, so a
new rotom-ng endpoint works here with no change. Proxied requests are
stripped of this service's own credentials before the instance's secret
is injected. Failures are distinguished: 404 for an unconfigured
instance, 502 for one that did not answer, 503 for none reachable.

The selection persists across visits and survives its instance going
down: the page reports that instance as unreachable rather than moving
the operator to a different server.

rotom-ng gains http_listener.disable_ui, which withholds its own web UI
so a listener fronted by this service need not expose a browser surface.
Applied per request, so a config reload turns it on and off.

Both binaries build from one multi-target Dockerfile and publish as
images from the same commit. Note the naming: apps/rotom-ng-ui/ is the
React app, so the Go service lives in apps/rotom-ng-ui-server/ and builds
a binary named rotom-ng-ui; "make rotom-ng-ui" builds that binary and
"make ui" builds the React bundle.
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