# Adventure Land behind Caddy 2 # # Replace before use: # al.example.com -> public hostname (DNS A/AAAA must point at the Caddy host) # 10.10.16.28 -> LAN/VPN address of the Docker host running the stack # # Caddy gets/renews the certificate automatically; TCP 80 and 443 must reach # the Caddy host. For an internal-only name use `tls internal` instead. { # email you@example.com } al.example.com { encode zstd gzip # --- Game server (container port 7192) ------------------------------ # /socket.io/ browser <-> game (WebSocket) # /socket.io-msgpack/ alternate parser used by the msgpack client # /server.api/ backend -> game (server_eval, protected by ACCESS_MASTER) @game path /socket.io/* /socket.io-msgpack/* /server.api/* handle @game { reverse_proxy 10.10.16.28:7192 { # Overwrite, not append: Adventure Land reads the first # X-Forwarded-For entry for its IP limits. Without this a client # could send a fake header and bypass the limits. header_up X-Forwarded-For {remote_host} } } # --- Web backend (container port 8090) ------------------------------ # Everything else: HTML, JS, /api/*, static files. handle { reverse_proxy 10.10.16.28:8090 { # Keep the public Host: the backend derives base_url and the # auth cookie domain from it. header_up Host {host} # Overwrite the client IP; see the game handler above. header_up X-Forwarded-For {remote_host} } } # Internal-only TLS (no Let's Encrypt). Clients must trust Caddy's CA. # tls internal # Optional hardening: only the Docker host may call the game's server API. # When enabling this, remove /server.api/* from the @game matcher above. # @serverapi { # path /server.api/* # remote_ip 10.10.16.28 # } # handle @serverapi { # reverse_proxy 10.10.16.28:7192 # } }