webstation-broker
Deployment

Troubleshooting

Symptom-first fixes for the failures that come up wiring a container behind a reverse proxy: cross-origin breakage, broker secret mismatches, dead-on-load rooms, and stale sessions.

Start here by symptom. Most of these trace back to the reverse proxy contract or the config.yml keys covering host, broker_host, subfolder and broker_secret.

This page is scoped to reverse-proxy and cross-origin failures. For other setup problems (the container won't start, the stream stays black, a specific game won't launch), see Troubleshooting.

You get no permission prompt at all, and the invite buttons fall back to a manual copy box instead of copying the link automatically. This is a cross-origin problem: browsers only fully trust a page when it's served from the same website address ("origin") as the page around it. Here, host in config.yml points at a different origin than RomM's (its own domain, or RomM's host on another port or scheme), so the browser treats the room as a different website and blocks it from ever asking for camera, microphone, or clipboard access. No reverse-proxy setting can fix this. See the callout at the top of Reverse proxy for why, and the RomM-side section there for the config change that actually fixes it (serving the container from a subfolder of RomM's own origin).

Room loads, then just sits there dead

The page and its assets are all loading fine, so this isn't a URL-prefix problem. It's the websocket connection (the live, two-way link the room uses for chat and game controls) failing to open. Check:

  • Make sure your proxy is actually forwarding the Upgrade and Connection: upgrade headers on this specific route, not just for the site as a whole. This trips people up especially in Nginx Proxy Manager: turning on the Proxy Host's Websockets Support toggle doesn't reliably carry over to a Custom Location you've added, so paste the upgrade headers into that location's own Advanced box too, whether or not the toggle is on. See the Nginx Proxy Manager tab for the exact lines to paste.
  • Check that proxy_read_timeout (or whatever your proxy calls the same setting) is set long enough that it won't cut off an idle session's connection in the middle of a game.

Assets 404, or the page loads with a broken layout

Your reverse proxy is stripping off the mount path (the URL prefix, such as /streaming) before it forwards the request. This is exactly the problem the contract page warns about: most proxies strip that prefix by default. On nginx, that usually means an extra path piece got added to proxy_pass. On Traefik, it's a stripPrefix middleware. On Caddy, it's using handle_path instead of handle. Run the curl checks under Verifying to see which side is wrong: if the asset src links on the page are missing the prefix, SUBFOLDER isn't set; if they have the prefix but still 404, the proxy is stripping it.

RomM says "This container's host has no scheme, so it can never be claimed"

This means host in config.yml is just a bare path (/streaming), with no https:// and domain name in front of it. Give it a full URL on RomM's own domain instead, for example https://romm.example.com/streaming. That keeps everything on the same origin, so none of the cross-origin problems described above apply, while still satisfying RomM's check. Leave subfolder and broker_host as they were. Only host needs to change.

Session looks claimed but nothing responds, even after fixing config.yml

Two separate things can cause this. It's worth ruling out both:

  1. RomM only reads config.yml when it starts up, not on every request. You need to restart RomM for it to pick up any edit to host, broker_host, subfolder, or broker_secret.
  2. A session that was claimed under the old settings is still using the old address. After restarting, end that session from RomM's streaming settings (or wait for it to expire), instead of expecting the new config to fix a session that's already in progress.

Traefik sends /streaming/ to RomM, or answers with an intermittent 502

Both symptoms come from the Traefik labels rather than the container.

  • RomM's page loads at /streaming/ instead of the room. RomM's router matches every path on the domain, and it is winning over the container's. Give the container's router a higher priority than RomM's.
  • Some requests work and others return 502 Bad Gateway. The service is attached to more than one Docker network and Traefik is sometimes using an address on a network it isn't part of. Set traefik.docker.network to the network Traefik shares with the service.

The Traefik tab has a full example with both settings.

Activate/join/exit calls fail with 403, and the broker log shows rejected request: bad or missing broker secret

BROKER_SECRET on the container and broker_secret in RomM's config.yml entry for that container are two separate settings, and they both need to be set to the same value. Setting one and not the other, or setting them to different values, produces this exact log line. If BROKER_SECRET isn't set on the container at all, this check doesn't run at all, so seeing this warning tells you it is set, and the two sides just disagree. See BROKER_SECRET and the config.yml example in Wiring it into RomM. If RomM has STREAMING_BROKER_SECRET set in its environment, that value is used instead of broker_secret for every container, so check it too.

Where to look next

  • The broker's own logs are the best source of truth for anything happening server-to-server (activate, join, exit, the secret check above). Your browser's console only shows what actually reaches the browser.
  • In your browser's developer tools, the network tab filtered to WS (short for websocket) is the fastest way to tell two failure modes apart: "the websocket never upgraded" (you never see a 101 response) versus "it upgraded and then dropped" (usually a proxy timeout).
  • Reverse proxy has the full contract and per-proxy recipes if none of the symptoms above match what you're seeing.

On this page