By default the DataMind Installer serves the web UI and the API from the same container and the same origin, so there is no proxy to configure and no CORS to get wrong. Connectivity problems appear when that single-origin assumption is broken: the browser is pointed at a different origin, PLATFORM_URL is malformed, or a reverse proxy in front is not forwarding the API. Each symptom below names where the break is.
The browser cannot reach http://<host>:<port>/, or gets a connection refused.
The UI is a single-page app served by the backend at ${NEST_PORT:-8000}; the backend is the only process you need reachable for the UI. If nothing answers, either the container is not running, or the port is not published, or a firewall is in the way.
Confirm the container is up and healthy — see Updates and startup.
Confirm the port is published and matches NEST_PORT:
docker ps --format '{{.Names}}\t{{.Ports}}'Test from the host itself, bypassing any firewall or proxy:
curl -s http://localhost:8000/api/health
Healthy output is {"status":"ok","db":"up"}. If this works but the browser does not, the problem is the network path to the host, not the Installer.
The page renders, but data does not load and the browser console shows failed requests to the wrong URL — often a 404, or a request to a path relative to the page.
The UI reads its API base URL at runtime from a small generated config file, not at build time. The build is identical everywhere; only this file differs:
/config.js (source: public/config.js) → window.APP_CONFIG.BASE_URL
index.html loads /config.js before the app bundle, and the app resolves the base as window.APP_CONFIG?.BASE_URL ?? ''. The default BASE_URL: '' means same-origin: the API lives at /api on the same host that served the page. That is the correct value for the standard install.
A non-empty BASE_URL (for example http://host:8089) switches the UI to cross-origin mode, and the backend must then allow that origin.
BASE_URL empty. A stray value here is the most common cause of "the UI loads but the API does not".BASE_URL when the UI is deliberately served from a different origin than the API. In that case you must also add that origin to the backend's CORS allowlist (NEST_ORIGINS) — see below.http://<host>:<port>/config.js and checking the value.NEST_ORIGINS is irrelevant in the default setup, precisely because the Installer serves the UI same-origin. Only set it if you point the UI at this backend from a different origin.
The browser console reports a CORS error; the request is blocked before it reaches the API.
The backend sends a CORS allowlist taken from NEST_ORIGINS. In the default same-origin install the browser sends no cross-origin request, so the list never matters. The moment the UI is served from another origin — a separate static host, or a different hostname — that origin must be in the allowlist, and credentials are allowed only for listed origins.
Add the UI's exact origin (scheme, host and port) to NEST_ORIGINS in the Installer configuration, comma-separated for several. Then reload the UI. A missing scheme, or a scheme that does not match what the browser sends, matches nothing.
PLATFORM_URL breaks derived URLsAny of:
PLATFORM_URL cannot be empty PLATFORM_URL is not a valid address: "<value>" PLATFORM_URL must be an http:// or https:// address, got "<protocol>"
Or, more subtly, no error at all — but the UI loads while its styles/scripts resolve against the wrong path and 404, or the platform's own UI cannot be reached.
PLATFORM_URL is the root of every derived URL the Installer writes into .env: NEST_ORIGINS, the frontend's BASE_URL / BASE_URL_BI / BASE_URL_SERVICE_METRICS, and REDASH_HOST / UNISTREAM_URL. It is normalised on every write path, so it always carries a scheme:
*.localhost, *.local, and any IP literal default to http;A scheme-less value is not cosmetic. It propagates into NEST_ORIGINS, which the platform's reverse proxy compares against the browser's Origin: header — a header that always carries a scheme, so a scheme-less value matches nothing. It also turns the frontend's BASE_URL* values into document-relative paths that 404.
PLATFORM_URL as a full http:// or https:// address. The Installer infers the scheme for you when it can, but an address it cannot parse is rejected with the messages above..env generation./apiThe UI loads through the proxy, but API calls return 404, or the SSE log stream never connects.
The backend serves the SPA at / and the API under the /api prefix; there is no separate static server. A reverse proxy placed in front must forward both — the SPA routes and /api — to the same backend port. Proxies that forward only / serve the page but drop /api, producing exactly this symptom.
/api (and the SSE endpoint /api/deployment/jobs/<jobId>/logs) to the backend, not only /.index.html — the backend already does this fallback; the proxy must not intercept it.PLATFORM_URL must be the public URL the browser uses, scheme included, or the derived BASE_URL* and NEST_ORIGINS values will point at the wrong place (see above).The DataMind Installer's own compose file publishes plain HTTP on its port and configures no certificates, so the Installer is reached over HTTP unless something in front adds TLS.
Another service on the same host, on the unistream network, fails to resolve or connect to the Installer.
The Installer joins the shared unistream network under a pinned DNS alias, delamain-backend, rather than under its container name — because the container name carries a -dev suffix on the development stack. Services on that network that address the Installer by its alias resolve it only while both are attached to the same unistream network.
unistream network, and that the network exists (create it once with docker network create unistream if missing).delamain-backend, not by its container name.If the Installer's API is reachable but rejects calls with an authentication error, the credential is the problem, not connectivity. Some paths expect the shared service token the Installer generates on first boot and writes into the platform .env; a reinstall that recreated the secrets volume rotates it, and the dependant service must pick up the new value.