How it works
The behavior of Caddy depends on the value ofCADDY_PUBLIC_HOST:
Caddy handles certificate renewal automatically once the initial certificate is issued.
Local development (HTTP only)
With the default settings from.env.example, the stack runs on http://localhost with no TLS:
localhost. The app is fully functional over HTTP for development purposes.
CORS_ORIGIN=http://localhost is the correct value when running locally with Docker + Caddy. Do not use https:// for local development unless you configure a self-signed certificate separately.Production HTTPS
1
Point DNS at your server
Create an A record for your hostname that resolves to your server’s public IP address. Let’s Encrypt uses an HTTP-01 challenge — it makes an HTTP request to your domain on port 80 to verify you control it. DNS must be propagated and port 80 must be reachable before you start the stack.Verify DNS is ready:
2
Set CADDY_PUBLIC_HOST and CADDY_EMAIL
In your Caddy registers a Let’s Encrypt account using
.env, set the hostname (no scheme, no trailing slash) and a Let’s Encrypt account email:CADDY_EMAIL the first time it obtains a certificate. The email receives expiry warnings if automatic renewal ever fails.3
Set CORS_ORIGIN to the HTTPS origin
Update Without this, the browser will receive CORS errors on all API calls.
CORS_ORIGIN to match the HTTPS origin users will open:4
Start or restart the stack
WebSocket and HTTPS
Hyperspeed uses WebSockets for realtime features (collaborative editing, live board updates, terminal). Behind HTTPS, WebSocket connections usewss:// instead of ws://.
Caddy handles the WebSocket upgrade automatically — no extra configuration is needed. The Caddyfile routes /api/* to the API container with reverse_proxy, which passes Upgrade and Connection headers through by default.
Using Traefik or nginx instead of Caddy
If your infrastructure already uses Traefik or nginx as an edge proxy, you can replace Caddy with your preferred reverse proxy. The routing requirements are:- All traffic to
/api/*and/healthmust proxy to the API container on port 8080, with WebSocket upgrade headers forwarded. - All other traffic should serve the web container on port 80.
- The API and web UI must share a single origin in the browser — the SPA calls
/api/...relative to the page origin. - TLS must terminate at the edge proxy.
When using an alternative proxy, remove or disable the
caddy service from docker-compose.yml and configure your proxy to handle TLS for your hostname. Set CADDY_PUBLIC_HOST and CADDY_EMAIL to empty or remove them — they are only read by the Caddy container.