WebSocket proxying is not the default
By default, most HTTP-1.1 reverse proxies do not forward the Upgrade header, which means the WebSocket handshake fails with a 400 from the proxy itself. You have to explicitly enable it. Once enabled, increase idle timeouts so long-lived WebSocket connections do not get killed mid-session.
Nginx vs Caddy
Nginx requires explicit proxy_set_header Upgrade $http_upgrade and Connection $connection_upgrade. Caddy detects WebSocket and forwards everything automatically — no special config. For a quick proof-of-concept, Caddy wins on ergonomics; Nginx is the default in production for reasons of familiarity, not capability.