Skip to content

Reverse Proxy

In docker and hybrid network modes, norsk-ctl runs an nginx reverse proxy (norsk-proxy) as the single entry point for browser traffic. It terminates TLS (optional), enforces authentication, and routes requests to the correct instance’s containers by matching the instance ID in the URL path.

In host mode there is no proxy — each instance binds its ports directly to the host.

  • Single external port — all instances reachable through one URL instead of one port per instance
  • Path-based routing — each instance lives at /instance/<id>/…
  • Authentication — HTTP Basic Auth (htpasswd) or OAuth2 (via oauth2-proxy)
  • TLS termination — HTTPS at the edge, plain HTTP to upstreams on norsk-net
  • Zero-downtime reload — adding instances or users doesn’t drop live connections

See Architecture for a diagram of how proxied and direct (ingest) traffic flow together.

Each running instance surfaces several paths under /instance/<id>/:

PathUpstreamPurpose
/instance/<id>/studio/norsk-studio-<id>:8000Studio UI (with WebSocket upgrade)
/instance/<id>/media/norsk-media-<id>:8080Media HTTP API
/instance/<id>/visualiser/norsk-media-<id> (visualiser port)Pipeline visualiser
/instance/<id>/uvis/norsk-media-<id> (visualiser port)Unified visualiser (WebSocket)
/instance/<id>/statusnorsk-media-<id> (visualiser port)Instance status endpoint
/api/host.docker.internal:8333norsk-ctl daemon API
/host.docker.internal:8333norsk-ctl web UI
Network modeHTTPHTTPS
docker90809443
hybrid80443
host— (no proxy)

Override via the PROXY_PORT environment variable if needed.

norsk-ctl proxy start # Start the nginx container and generate config from running instances
norsk-ctl proxy stop # Stop and remove the proxy container
norsk-ctl proxy reload # Regenerate config and reload nginx (zero-downtime)
norsk-ctl proxy status # Show proxy container status and active upstreams
norsk-ctl proxy pull # Pre-pull the nginx (and oauth2-proxy, if applicable) images
norsk-ctl proxy logs # View access or error logs (--type access|error, -n, -f)

norsk-ctl init starts the proxy automatically in docker and hybrid modes. Subsequent launches trigger a proxy reload, so you rarely run these commands by hand.

Two modes are supported, picked at norsk-ctl init time:

Users live in an nginx htpasswd file managed via the user subcommands.

Terminal window
# Add or update (prompts for password, or use --password / stdin)
norsk-ctl user set alice
# Remove a user
norsk-ctl user delete alice

Changes take effect immediately — the daemon writes the htpasswd file and tells nginx to reload without dropping connections. No manual proxy reload needed.

For deployments fronted by an identity provider (Google, Okta, etc.), norsk-ctl can run oauth2-proxy alongside nginx. Enable at init by passing OAuth2 credentials — the proxy then redirects unauthenticated users through the IdP before routing to the upstream.

Enable with --cert-path and --key-path at norsk-ctl init. The proxy adds an HTTPS server block listening on the TLS port (9443 / 443 depending on mode), with:

  • TLSv1.3 only
  • Post-quantum cipher group X25519MLKEM768 + TLS_AES_256_GCM_SHA384
  • HTTP/2 enabled

Plain HTTP requests to the HTTP port are redirected to HTTPS.

Certificate provenance is tracked via certSource in config.yamlmkcert for local dev, user for a bring-your-own cert, certbot for auto-renewed Let’s Encrypt.

Terminal window
# Tail access log
norsk-ctl proxy logs --type access -f
# Last 200 lines of the error log
norsk-ctl proxy logs --type error -n 200

Both also appear in the Logs → Proxy view in the web UI.