Skip to main content

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.

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.

How it works

The behavior of Caddy depends on the value of CADDY_PUBLIC_HOST:
CADDY_PUBLIC_HOSTResult
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.
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:
CADDY_PUBLIC_HOST=localhost
This is intentional — Let’s Encrypt does not issue certificates for 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:
dig app.example.com
2

Set CADDY_PUBLIC_HOST and CADDY_EMAIL

In your .env, set the hostname (no scheme, no trailing slash) and a Let’s Encrypt account email:
CADDY_PUBLIC_HOST=app.example.com
CADDY_EMAIL=you@example.com
Caddy registers a Let’s Encrypt account using 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 CORS_ORIGIN to match the HTTPS origin users will open:
CORS_ORIGIN=https://app.example.com
Without this, the browser will receive CORS errors on all API calls.
4

Start or restart the stack

docker compose up --build -d
Caddy requests the certificate on first start. Watch for errors:
docker compose logs -f caddy
A successful certificate issue looks like:
certificate obtained successfully
If port 80 is blocked by a firewall or already in use by another process, the HTTP-01 challenge will fail and Caddy will not be able to obtain a certificate. Ensure ports 80 and 443 are both open and free before starting the stack.

WebSocket and HTTPS

Hyperspeed uses WebSockets for realtime features (collaborative editing, live board updates, terminal). Behind HTTPS, WebSocket connections use wss:// 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.
To verify WebSocket connectivity: open a space with realtime features and check DevTools Network for a 101 Switching Protocols response on the /api/v1/organizations/.../ws connection.

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 /health must 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.
An example nginx location block for the API:
location /api/ {
    proxy_pass http://api:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}
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

SymptomLikely 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 DevToolsCORS_ORIGIN does not exactly match the origin in the browser address bar. Scheme, host, and port must all match.
WebSocket connection fails behind HTTPSThe proxy is not forwarding Upgrade and Connection headers. Add the WebSocket upgrade headers to your proxy config.
Port 80 already in useAnother 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).