# Caddyfile for the Ergo stack. Caddy runs in the HOST network namespace. # # Roles: # 1. Obtain and renew the Let's Encrypt certificate for {$ERGO_DOMAIN}. Ergo's # :6697 listener reuses that cert -- `update.sh certsync` copies it into # ./ircd and rehashes Ergo (runs every 15 minutes, silent when unchanged). # 2. Terminate HTTPS for IRC-over-WebSocket: wss://{$ERGO_DOMAIN}/webirc -> # Ergo's plaintext websocket listener on 127.0.0.1:8097. Caddy adds # X-Forwarded-For / X-Forwarded-Proto and Ergo trusts them from loopback # (proxy-allowed-from: localhost), so web users keep their real IP and are # marked secure (+Z). # 3. A plain-text landing page with connection details at /. # # Add your own site config (e.g. a Gamja web client, see README) as # conf.d/*.caddy -- deploy.sh installs this file but never touches conf.d/. # Apply changes with: docker compose restart caddy { email {$ACME_EMAIL} # Host networking would put the admin API on the HOST's 127.0.0.1:2019, # reachable by every local process and container. The config is static, so # turn it off; changes are applied by restarting the container. admin off # No HTTP/3: it would bind udp/443 on the host (not in the firewall's port # list) and browsers do not run WebSockets over h3 anyway. servers { protocols h1 h2 } } # Loopback-only health endpoint for the compose healthcheck (no admin API to ask). http://127.0.0.1 { respond "ok" 200 } {$ERGO_DOMAIN} { encode zstd gzip # IRC over WebSocket. Ergo ignores the request path; Caddy proxies the # Upgrade transparently and supplies X-Forwarded-For/-Proto itself. handle_path /webirc* { reverse_proxy 127.0.0.1:8097 } # Operator additions (web client, redirects, ...). See conf.d/00-readme.caddy. import conf.d/*.caddy handle { header Content-Type "text/plain; charset=utf-8" respond < Powered by Ergo (https://ergo.chat). TXT 200 } header { Strict-Transport-Security "max-age=31536000; includeSubDomains" X-Content-Type-Options "nosniff" Referrer-Policy "strict-origin-when-cross-origin" -Server } log { output stdout format console } }