nivq
This install section is for Enterprise / on-prem customers who self-host nivq.

Web client (UI)

Run the nivq web client — the browser UI users open. A static single-page app served by nginx (or any webserver), configured at runtime so one build runs anywhere — Docker, Kubernetes, or bare metal.

The three install paths — Quickstart, Kubernetes, Bare metal — bring up the API. The web client is the browser UI your users open, and it ships as a separate static single-page app: built once, served by a webserver, pointed at your nivq API. You run it alongside the API in every mode.

One build, configured at runtime

The UI is a plain static bundle. The settings that change per deployment — your API URL, auth server, OIDC client id — are read at runtime, not baked into the build. So the same image (or the same dist/ folder) runs in every environment with no rebuild; you just point it at your API.

Pull the image

The web client is a private image (ghcr.io/nivorbit/images/nivq-web), same registry and login as the API. It's a static build behind nginx on port 8080, non-root:

Shell
docker pull ghcr.io/nivorbit/images/nivq-web:0.2.2

Configure it — at runtime

Two equivalent ways; pick whichever fits your platform.

A. Environment variables (recommended for Docker & Kubernetes)

On start, the container renders its config from environment variables. Only NIVQ_API_BASE_URL is required:

VariableDefaultWhat it is
NIVQ_API_BASE_URL(required)Your nivq API URL (BACKEND_URL), as reached from the browser
NIVQ_AUTH_SERVER_URL= NIVQ_API_BASE_URLOIDC issuer — the API is its own identity provider, so leave it
NIVQ_CLIENT_IDnivq-appOIDC client id — leave it unless you changed it on the API
NIVQ_WORKSPACE_NAMENivQName shown in the UI
NIVQ_PRIMARY_COLOR#f35553Brand accent colour
Shell
docker run -d --name nivq-web -p 3000:8080 \
  -e NIVQ_API_BASE_URL=https://api.example.com \
  ghcr.io/nivorbit/images/nivq-web:0.2.2

B. A config file (for mounting, or serving on your own webserver)

The app reads /config/default.json at startup. Leave NIVQ_API_BASE_URL unset and mount your own file — it's used as-is:

JSON
{
  "apiBaseUrl": "https://api.example.com",
  "authServerUrl": "https://api.example.com",
  "clientId": "nivq-app",
  "scope": "openid profile email",
  "workspaceName": "Your Company",
  "primaryColor": "#f35553"
}
Shell
docker run -d --name nivq-web -p 3000:8080 \
  -v ./config/default.json:/usr/share/nginx/html/config/default.json:ro \
  ghcr.io/nivorbit/images/nivq-web:0.2.2

Open http://localhost:3000 — you should land on the sign-in page. Put TLS in front of it in production, just like the API.

Serve it on your own webserver

Don't want the container? The build is a plain static bundle (dist/). Copy it to your webserver's docroot, drop a config/default.json beside it (option B above), and serve it. Two rules make an SPA work:

  1. Fall back to index.html for unknown routes (client-side routing) — but not for /config/, /assets/, or /locales/, so a missing file there returns 404 rather than HTML.
  2. Never cache /config/default.json, so config edits take effect on reload.

Starter configs ship in the repo: deploy/nginx.conf and deploy/apache.conf (mod_rewrite + mod_headers).

How sign-in fits together

nivq signs users in with OIDC (Authorization Code + PKCE) against the API itself — there's no separate auth server to run. On boot, the API automatically registers the web client with a redirect URI of <FRONTEND_URL>/auth/callback. Two rules follow:

  1. Set the API's FRONTEND_URL to the web client's public URL (e.g. https://app.example.com).
  2. Serve the web client at exactly that URL.

The match is exact — if the SPA is loaded from any other origin, the API rejects the login. After that, sign-in goes through whichever provider you configured on the API (Google, Microsoft, GitHub — see Authentication & SSO); the web client shows those as buttons.

One origin, set on both sides

The web client's public URL, the API's FRONTEND_URL, and NIVQ_API_BASE_URL (or apiBaseUrl) all have to agree. A login that bounces back to the sign-in page is almost always an origin mismatch here.

Per deployment mode

  • Docker / Compose — add the nivq-web service next to the API; the Quickstart compose already includes it.
  • Bare metal — run the same container with a reverse proxy in front, or serve dist/ on the webserver you already run. See Bare metal.
  • Kubernetes — the Helm chart deploys the web client too when you enable it. See Kubernetes.