Hyperspeed uses Caddy as its public entrypoint on ports 80 and 443. Caddy handles TLS automatically when you provide a real hostname. No certificate management tooling is needed beyond setting two environment variables.Documentation Index
Fetch the complete documentation index at: https://hyperspeed.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
How it works
The behavior of Caddy depends on the value ofCADDY_PUBLIC_HOST:
CADDY_PUBLIC_HOST | Result |
|---|---|
localhost (default) | HTTP only on port 80. No TLS. Use for local development. |
A real FQDN (e.g. app.example.com) | Caddy obtains a Let’s Encrypt certificate automatically via HTTP-01 challenge and serves HTTPS on port 443. |
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
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:
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.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: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.Troubleshooting
| Symptom | Likely cause |
|---|---|
| Browser shows “certificate not trusted” | DNS was not propagated when the stack started; Let’s Encrypt challenge failed and Caddy fell back to a self-signed cert. Fix DNS, then restart Caddy. |
| CORS errors in browser DevTools | CORS_ORIGIN does not exactly match the origin in the browser address bar. Scheme, host, and port must all match. |
| WebSocket connection fails behind HTTPS | The proxy is not forwarding Upgrade and Connection headers. Add the WebSocket upgrade headers to your proxy config. |
| Port 80 already in use | Another process is bound to port 80. Stop it or change the Compose port mapping (note: HTTP-01 challenge requires port 80 to be the public port). |