Standalone F8 Studio
F8 Studio can ship baked into the all-in-one container, served same-origin from the API
app’s wwwroot (Running). You can also deploy it standalone: a
small static (nginx) container that serves the SPA and is pointed at an arbitrary Fallen-8 REST
data plane at container start. This decouples where the UI runs from where the data plane runs,
without a rebuild.
The default npm run env:up runs F8 Studio this way: its own container talking to the data plane.
The all-in-one (UI baked into the API container) remains available with a bare docker compose up.
How it learns which data plane to talk to
Section titled “How it learns which data plane to talk to”The UI runs in the browser, so it needs the browser-reachable URL of the REST API. A standalone
build carries a tiny config.js that sets a global before the app loads:
window.__F8_CONFIG__ = { apiUrl: "https://graph.example.com" };The container’s entrypoint rewrites that one file from the F8_API_URL environment variable every
time it starts, so one built image can front any endpoint. An empty apiUrl (the default) means
same origin, which is the all-in-one behaviour. The Connect screen still lets a user add or
switch to other instances by hand.
A quote, backslash, or newline in F8_API_URL would break out of that JS string literal, so the
entrypoint refuses to start instead of writing a broken config.js: nginx never comes up and
the log carries f8-config: F8_API_URL contains a quote or backslash; refusing to start (or
… contains a newline …). Check docker logs when the UI container will not start.
Run it locally
Section titled “Run it locally”The default dev environment already runs this topology: a UI-less data plane plus the standalone UI container (the full set of topologies is in Running):
npm run env:up # REST data plane on :8080, F8 Studio UI on :8081npm run env:upF8_UI_PORT (default 8081) sets the UI’s host port and F8_PORT (default 8080) the data plane’s.
A bare docker compose up (no overlay) instead runs the all-in-one, with the UI baked into the API
container on :8080.
CORS: allow the UI’s origin
Section titled “CORS: allow the UI’s origin”A UI on one origin calling a data plane on another is a cross-origin request (a different port counts), and Fallen-8’s CORS is deny-all by default. Allow the UI’s origin on the data plane:
Fallen8__Security__AllowedCorsOrigins__0=http://localhost:8081The indexed __0 suffix is required to bind the array; a bare key does not. The split overlay wires
this for you. If a cross-origin instance reads as “unreachable” on the Connect screen while the data
plane is actually up, a missing allow-list entry is the usual cause, and Studio surfaces that hint
for exactly this case. See Security.
A model backend the browser calls directly needs the UI origin allowed too, on that backend:
OLLAMA_ORIGINS for your own Ollama. The split overlay sets both allow-lists. See
NL assist.
Build the image yourself
Section titled “Build the image yourself”The image builds from the repo root (so the SPA build reaches the bundled sample datasets):
docker build -f fallen-8-web-ui/Dockerfile -t f8-studio .docker run -p 8081:80 -e F8_API_URL=https://graph.example.com f8-studioIt serves the SPA with a client-side-routing fallback, ships the bundled sample datasets at
/samples (where the gallery fetches them same-origin), and never caches config.js (so an
endpoint change takes effect on the next load). Hosting under a sub-path is not supported: assets
resolve from the origin root.
Instances: managed vs personal
Section titled “Instances: managed vs personal”The endpoint from config.js is a managed default instance: it is synthesized fresh on every
load (so changing F8_API_URL propagates) and cannot be removed. Because it is never persisted, it
also carries no credential: config.js sets only apiUrl, and an API key typed into the managed
record with Edit works for that session and is gone on the next load (the instance reads
unauthorized again).
So against a key-secured data plane each user registers a personal instance pointed at the data plane’s URL with the key: personal instances, keys included, persist in the browser untouched. See Security for the key itself, and F8 Studio for the instance model and the Connect screen.
See also
Section titled “See also”- Running: every way to launch it
- F8 Studio: the UI itself and the Connect screen
- Security: the API key and the CORS allow-list
- Architecture: how the standalone UI fits the whole