Skip to content

Configuration

Who this is for: hosters (sysadmins) and technical readers.

This page lists the important settings for the stack: the speech service token, the relay's private configuration, the capture-page auto-fill file, and the UI and production variables. Values marked required must be set for that feature to work.

Shared-token model

This stack uses shared tokens, not user accounts. There are no per-user keys, invitation links or tenant separation. Anyone who holds a token can do everything that token allows. Share tokens privately and rotate them by restarting the service with new values.

Secrets layout

Two directories hold credentials, and both are used only by the services that need them:

  • secrets/caption-local.env — loaded into the speech service.
  • secrets/relay-tokens.env — loaded into the speech service for the /relay-config endpoint.
  • secrets/relay.private.json — read by the relay.
  • secrets/traefik.htpasswd — read by Traefik only when the Basic Auth overlay is applied.

The secrets/ directory is git-ignored, and so are *.private.json files. The tracked .env.production file is non-secret — keep credentials out of it.

Speech service

Setting Purpose Required Default
CAPTION_API_KEY Service access token. When set, every API route requires Authorization: Bearer <token>. Gates health, model listing, inference and session deletion; static UI stays loadable. No Unset (trusted-loopback model)
CAPTION_ALLOWED_ORIGINS Comma-separated exact HTTPS origins allowed to call the service. Only together with CAPTION_API_KEY Unset

Use at least 24 ASCII characters with no whitespace for CAPTION_API_KEY. The env file is declared required: false, so it can be omitted entirely for the default loopback setup. See Access and sharing.

Relay private configuration

The relay reads secrets/relay.private.json (override the path with CAPTION_RELAY_CONFIG). It is generated with init-config.cjs and must be readable by uid/gid 1000.

Setting Purpose Required Default
origins List of exact browser origins allowed to open a WebSocket. Scheme included, no trailing slash. Yes None (generated defaults are loopback origins)
Room tokens The source and output room read/write tokens used to publish and subscribe. Yes None (generated by init-config.cjs)

A connection whose origin is not listed is rejected; a missing capture origin makes publishing fail with HTTP 403 and the overlay appear empty. List the capture host and the UI/overlay host if they differ. Recreate the relay after editing so it reloads the file.

Capture-page auto-fill (secrets/relay-tokens.env)

These keys let the capture page fetch its relay address, room names and tokens from the authenticated GET /relay-config endpoint and build ready editor and audience links. The endpoint returns 404 unless CAPTION_API_KEY is also set, and without the file the pages fall back to manual token entry.

Setting Purpose Required Default
RELAY_ADDRESS Relay WebSocket URL given to the capture page. Must be wss://. Yes for the endpoint Unset (endpoint stays off)
RELAY_SITE UI host base (with trailing slash) used to build editor/overlay links. Yes for usable links Unset
RELAY_ROOM Name of the source room. Yes for the endpoint No built-in default; example source
RELAY_OUTPUT_ROOM Name of the reviewed output room. Yes for the endpoint No built-in default; example output
RELAY_SOURCE_READ Read token for the source room. Yes for the endpoint Unset
RELAY_SOURCE_WRITE Write token for the source room. Yes for the endpoint Unset
RELAY_OUTPUT_READ Read token for the output room. Optional Unset
RELAY_OUTPUT_WRITE Write token for the output room. Optional Unset

Values must match the room tokens in the relay's private JSON. The RELAY_OUTPUT_* tokens are optional: anyone holding the service access token can read everything the endpoint returns, so leave the output write token out if capture operators should not publish to the audience room without the editor.

Web UI

Setting Purpose Required Default
RELAY_URL Relay WebSocket URL written into /site-config.js for the landing-page links. For working UI links Local: ws://localhost:8080/ws; production: wss://${RELAY_HOST}
CAPTURE_URL Capture host, with trailing slash. When set, / serves links.html; when empty, / serves index.html. For the links hub Local: http://localhost:8765/; production: https://${CAPTURE_HOST}/

Both are set by docker-compose.prod.yml from the hostname variables below. There is no built-in relay or caption site to fall back to.

Production hostnames and TLS

Set these in the tracked, non-secret .env.production file and pass it with --env-file .env.production. See Deploy with Docker Compose. For the Co-op Cloud recipe, the domain and secrets are managed through abra — see Deploy with Co-op Cloud.

Setting Purpose Required Default
LETSENCRYPT_EMAIL ACME account email for Let's Encrypt notifications, passed to Traefik. Yes for public TLS None
CAPTURE_HOST Hostname for the capture page and speech service. Yes in production None (Compose refuses to start)
RELAY_HOST Hostname for the relay; also derives the UI RELAY_URL. Yes in production None (Compose refuses to start)
UI_HOST Hostname for the static UI. Yes in production None (Compose refuses to start)

The terms used here are defined in the Glossary.