Skip to content

Behind a reverse proxy

The control plane can sit behind a proxy. The stream never goes through it, so see Reaching Quasar remotely before expecting internet play.

Point your existing proxy at the control plane’s HTTP port (8080 by default), not 8443. The examples below use quasar.example.com and a control plane at quasar.lan:8080; replace both with your addresses.

  • Pass the original Host and send X-Forwarded-Proto. The signaling address is built from them; owned installs have no PUBLIC_BASE_URL. The examples below do this.

  • Add the public URL to allowed origins in Admin ▸ Settings. Opening first-run setup through the public address saves it for you. There is no environment override on an owned install.

  • Set QUASAR_TRUSTED_PROXIES (a seed input) to your proxy’s address or CIDR. Until it is set, first-run setup and sign-in through the proxy are refused. An owned install always serves HTTPS, so sign in on its HTTPS port (8443) meanwhile. To change it later, on the first machine:

    Terminal window
    docker exec -it quasar-recovery quasar-recovery reconfigure --yes QUASAR_TRUSTED_PROXIES=<address or CIDR>

Keep QUASAR_PUBLIC_HOST for direct LAN access on the HTTPS port.

These add Quasar to an existing proxy; they do not install the proxy or configure its certificate. Keep your current certificate settings.

# Add to your existing Caddyfile. Caddy forwards WebSocket upgrades and
# sets X-Forwarded-* on its own, so this stays short.
quasar.example.com {
reverse_proxy http://quasar.lan:8080 {
# Long-lived: /v1/signal and /agent/ws stay open for the whole session.
transport http {
read_timeout 3600s
write_timeout 3600s
}
header_up X-Forwarded-Proto https
flush_interval -1
}
}

The hardened overlay puts Caddy with ACME certificates in front and derives the URL and origins from QUASAR_PUBLIC_HOST in deploy/.env:

Terminal window
docker compose -f deploy/docker-compose.yml \
-f deploy/docker-compose.hardened.yml up -d

With your own proxy, set these in deploy/.env.

Terminal window
PUBLIC_BASE_URL=https://quasar.example.com

Needed when the proxy rewrites Host.

Terminal window
QUASAR_ALLOWED_ORIGINS=https://quasar.example.com

Gates the signaling WebSocket. Unset uses the list in Admin ▸ Settings; set (even empty), it overrides that list. With neither, only same-origin is allowed.

  • Comma-separated exact scheme://host[:port] entries, no path, query or credentials.
  • * is rejected. A malformed entry stops startup.
  • Keep your LAN origins (such as https://<lan-ip>:8443) when adding a public one.

The proxy’s address or network, and nothing broader. With the bundled Caddy, use that Compose project’s bridge subnet. Empty is safe: forwarded headers are ignored. That includes X-Forwarded-Proto, so first-run setup and sign-in through the proxy are refused until this is set. A proxy that is not listed shows up in the control plane’s log as forwarded-from-unlisted-peer with its address (once per 10 minutes). If that is your reverse proxy, put its address here. The way round it depends on the stack:

  • Default Compose stack: set up and sign in directly on the HTTPS port (8443).
  • Hardened overlay (no published control-plane port) or QUASAR_TLS=off (no HTTPS port): none. BOOTSTRAP_ADMIN_* creates an admin, but nobody can sign in until the proxy is named.
  • Forward WebSocket upgrades on /v1/signal and /agent/ws.
  • No buffering on those paths.
  • A long read timeout (a 60-second idle timeout cuts sessions).
  • Send X-Forwarded-Proto: https, set by the proxy, not passed through from the client.

Point node agents on the same machine or trusted network at the control plane directly (/agent/ws over HTTP), not through the proxy.

When your proxy already compresses responses, set QUASAR_COMPRESSION=false on the control plane and let the proxy do it.

  1. Open the console at the proxy address and run Admin’s access check.
  2. Connect through your LAN or VPN and launch a session.
  3. Confirm video, sound and input work. If the session never starts, check allowed origins and the client’s direct route to the host.