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.

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.
Hyperspeed supports one organization per database. The first user to register creates the workspace through a setup wizard. Subsequent users join via invites or open registration (with admin approval). If you need multiple isolated workspaces, run separate Compose stacks with separate databases.

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

1

Clone the full repository

SSH into your server and clone the entire repository. The Compose file builds apps/api and apps/web; a standalone docker-compose.yml is not enough.
git clone https://github.com/jasfromsolaris/Hyperspeed.git
cd Hyperspeed
All subsequent commands run from this directory (the repository root, where docker-compose.yml lives).
2

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.
app.example.com  A  203.0.113.10
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.
3

Configure your production .env

Copy the example file and set all required variables:
cp .env.example .env
The table below lists every variable you must set for a production deployment.
VariableRequiredDescription
JWT_SECRETYesHMAC key for access tokens. Use at least 32 random characters. Generate with openssl rand -base64 32.
HS_SSH_ENCRYPTION_KEYYesBase64-encoded 32 bytes. Encrypts stored SSH credentials for the terminal. Generate with openssl rand -base64 32.
CADDY_PUBLIC_HOSTYesHostname only — no scheme. Example: app.example.com. Caddy uses this for the site block and Let’s Encrypt.
CADDY_EMAILYesEmail address for your Let’s Encrypt account. Example: you@example.com.
CORS_ORIGINYesExact browser origin, scheme included. Example: https://app.example.com. Must match what users type in the address bar.
PUBLIC_API_BASE_URLYesSame public origin as CORS_ORIGIN. Used when the API must emit absolute URLs (for example, IDE file previews).
A minimal production .env looks like this:
JWT_SECRET=<output of: openssl rand -base64 32>
HS_SSH_ENCRYPTION_KEY=<output of: openssl rand -base64 32>

CADDY_PUBLIC_HOST=app.example.com
CADDY_EMAIL=you@example.com
CORS_ORIGIN=https://app.example.com
PUBLIC_API_BASE_URL=https://app.example.com
Do not include https:// in CADDY_PUBLIC_HOST. It must be the hostname only. Setting it to https://app.example.com will break Caddy’s site block.
4

Open required ports

Ensure your server’s firewall or security group allows inbound traffic on these ports:
PortProtocolServicePurpose
80TCPCaddyHTTP and ACME HTTP-01 challenge
443TCPCaddyHTTPS
8080TCPAPIDebug access to the API (optional; restrict in production)
If your hosting panel already occupies ports 80 or 443, consult your panel’s reverse-proxy documentation or adjust the port bindings in docker-compose.yml.
5

Build and start the stack

From the repository root:
docker compose up --build -d
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.
6

Verify the deployment

Check that the API is healthy:
curl https://app.example.com/health
A successful response looks like:
{"status":"ok","version":"1.0.0","git_sha":"abc1234"}
GET /health is the canonical health check endpoint. Use it in your load balancer, uptime monitor, or hosting panel’s health probe. It returns "status":"ok" when the API is running and connected to Postgres and Redis. The version and git_sha fields are populated when the image is built with the VERSION and GIT_SHA build args (set HYPERSPEED_VERSION and HYPERSPEED_GIT_SHA in .env and they are forwarded as build args by docker-compose.yml).
Then open https://app.example.com in a browser. The first visit triggers the setup wizard.
7

Complete the setup wizard

Register as the first user. Because no organization exists yet, the registration flow launches the setup wizard:
  1. Enter your name, email, and password.
  2. Name your workspace (organization).
  3. Review the hostname shown in the wizard — it should match your public URL.
After finishing, you are the workspace admin. Invite teammates from workspace settings.

Port reference

PortBound byNotes
80CaddyServes HTTP and handles Let’s Encrypt HTTP-01 challenges. Redirects to 443 in production.
443CaddyServes the app over HTTPS with a Let’s Encrypt certificate.
8080API containerDirect API access on the host. Useful for debugging; consider restricting with a firewall rule in production.

Environment variable reference

VariableRole
JWT_SECRETHMAC key for access tokens (required in production)
HS_SSH_ENCRYPTION_KEYBase64, 32 bytes — required for terminal SSH credential storage
CADDY_PUBLIC_HOSTHostname for Caddy’s site block (localhost = HTTP only; real FQDN = HTTPS via Let’s Encrypt)
CADDY_EMAILLet’s Encrypt account email when using a real hostname
CORS_ORIGINExact browser origin allowed for API calls (scheme + host, port only if non-standard)
PUBLIC_API_BASE_URLSame public origin users use in the browser; needed when the API emits absolute URLs
For all available variables including optional ones, see Environment Variables.

Workspace limit

The open-source Hyperspeed stack allows at most one organization per database. The first user to register creates that organization through the setup wizard. If you need multiple isolated teams, deploy separate stacks with separate databases — do not attempt to create a second organization in the same database.
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.com subdomains.
  • 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.