https://floe.example.com.
This is the recommended production layout. It means one certificate, one DNS record,
one value to configure, and share links that work without any extra setup.
Route table
The client and the signaling server claim different paths, so they coexist on one origin with no conflicts. Send these paths to the signaling server and everything else to the client.Proxy configuration
- Caddy
- nginx
Caddy handles HTTPS certificates and WebSocket upgrades automatically, so the
whole config is a handful of lines.
Floe configuration
Leave the socket URL empty. The browser then talks to whatever host it was loaded from, which behind this proxy is already the right answer.NEXT_PUBLIC_SITE_URL is the only build-time value here. The published image
cannot carry it, so canonical links and share previews are omitted rather than
pointed somewhere wrong. See Container Images to build the
client with your own domain baked in.
CLIENT_URL is matched exactly, including the scheme and with no trailing
slash. https://floe.example.com and https://www.floe.example.com are
different origins to the CORS check, so use whichever one your users actually
visit.TRUSTED_PROXY_COUNT must equal the number of proxy hops in front of the
signaling server. One reverse proxy means 1. A CDN in front of that proxy means
2. Setting it higher than your real hop count lets clients forge
X-Forwarded-For and slip past the per-IP rate limits.
Using the CLI with a one-domain instance
One address is all the CLI needs. The share link it prints resolves to the same origin, so it opens the web client correctly with no extra flag:--web flag only exists for split deployments where the client lives on a
different hostname than the signaling server.
TURN does not go through the proxy
If you run the optional coturn relay, its ports stay directly exposed. TURN is not HTTP, so a reverse proxy cannot carry it. See TURN Relay for the port list and firewall rules.Verify it works
https://floe.example.com in a browser. The connection badge should read
Ready. If it stays disconnected, the /socket.io/ route is the first thing to
check.
Prefer two subdomains?
Splitting the client and server acrossapp.your-domain.com and
api.your-domain.com is still fully supported. See
Production Deployment.