This guide covers deploying Hyperspeed on a public server — a VPS, a cloud VM, or a managed hosting panel that runs Docker Compose. Caddy handles TLS automatically using Let’s Encrypt once you point DNS at your server.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.
Requirements
- A server running Docker and Docker Compose v2
- Ports 80 and 443 available on the host (used by Caddy)
- A domain name with DNS you control
- The full repository cloned on the server — not just
docker-compose.yml
Deploy to a server
Clone the full repository
SSH into your server and clone the entire repository. The Compose file builds All subsequent commands run from this directory (the repository root, where
apps/api and apps/web; a standalone docker-compose.yml is not enough.docker-compose.yml lives).Point DNS at your server
Create an A record (and an AAAA record if your server has IPv6) for your chosen hostname pointing to the server’s public IP address.Caddy uses the HTTP-01 ACME challenge on port 80 to obtain a certificate from Let’s Encrypt. DNS must resolve before you start the stack, or certificate issuance will fail.
Configure your production .env
Copy the example file and set all required variables:The table below lists every variable you must set for a production deployment.
A minimal production
| Variable | Required | Description |
|---|---|---|
JWT_SECRET | Yes | HMAC key for access tokens. Use at least 32 random characters. Generate with openssl rand -base64 32. |
HS_SSH_ENCRYPTION_KEY | Yes | Base64-encoded 32 bytes. Encrypts stored SSH credentials for the terminal. Generate with openssl rand -base64 32. |
CADDY_PUBLIC_HOST | Yes | Hostname only — no scheme. Example: app.example.com. Caddy uses this for the site block and Let’s Encrypt. |
CADDY_EMAIL | Yes | Email address for your Let’s Encrypt account. Example: you@example.com. |
CORS_ORIGIN | Yes | Exact browser origin, scheme included. Example: https://app.example.com. Must match what users type in the address bar. |
PUBLIC_API_BASE_URL | Yes | Same public origin as CORS_ORIGIN. Used when the API must emit absolute URLs (for example, IDE file previews). |
.env looks like this:Open required ports
Ensure your server’s firewall or security group allows inbound traffic on these ports:
If your hosting panel already occupies ports 80 or 443, consult your panel’s reverse-proxy documentation or adjust the port bindings in
| Port | Protocol | Service | Purpose |
|---|---|---|---|
| 80 | TCP | Caddy | HTTP and ACME HTTP-01 challenge |
| 443 | TCP | Caddy | HTTPS |
| 8080 | TCP | API | Debug access to the API (optional; restrict in production) |
docker-compose.yml.Build and start the stack
From the repository root:Compose builds the API and web images, then starts all six services. Caddy contacts Let’s Encrypt and obtains a certificate for
CADDY_PUBLIC_HOST automatically.Verify the deployment
Check that the API is healthy:A successful response looks like:Then open
https://app.example.com in a browser. The first visit triggers the setup wizard.Complete the setup wizard
Register as the first user. Because no organization exists yet, the registration flow launches the setup wizard:
- Enter your name, email, and password.
- Name your workspace (organization).
- Review the hostname shown in the wizard — it should match your public URL.
Port reference
| Port | Bound by | Notes |
|---|---|---|
| 80 | Caddy | Serves HTTP and handles Let’s Encrypt HTTP-01 challenges. Redirects to 443 in production. |
| 443 | Caddy | Serves the app over HTTPS with a Let’s Encrypt certificate. |
| 8080 | API container | Direct API access on the host. Useful for debugging; consider restricting with a firewall rule in production. |
Environment variable reference
| Variable | Role |
|---|---|
JWT_SECRET | HMAC key for access tokens (required in production) |
HS_SSH_ENCRYPTION_KEY | Base64, 32 bytes — required for terminal SSH credential storage |
CADDY_PUBLIC_HOST | Hostname for Caddy’s site block (localhost = HTTP only; real FQDN = HTTPS via Let’s Encrypt) |
CADDY_EMAIL | Let’s Encrypt account email when using a real hostname |
CORS_ORIGIN | Exact browser origin allowed for API calls (scheme + host, port only if non-standard) |
PUBLIC_API_BASE_URL | Same public origin users use in the browser; needed when the API emits absolute URLs |
Workspace limit
If the API detects more than one organization in the database (for example after a legacy data migration), it logs a warning at startup and refuses to create additional organizations until only one remains.Next steps
- Custom domains and subdomains — See the Domains guide for BYO domain configuration and optional
*.hyperspeedapp.comsubdomains. - TLS behind another proxy — See the TLS guide if Caddy sits behind Traefik, nginx, or a cloud load balancer.
- Backups — See Backups for Postgres and MinIO backup strategies.
- Upgrades — See Upgrades for the upgrade process and breaking change notes.