DOCS

Self-hosting

Bring the whole qbox platform up on a single Linux host with one command, behind HTTPS.

qbox runs as a Docker Compose stack on one Linux box with hardware KVM: Postgres, NATS, object storage, the control plane, dashboard, template builder, host agent, and a Caddy reverse proxy that terminates TLS.

Requirements

qbox runs real Firecracker microVMs, so the host must expose hardware virtualization as /dev/kvm — a bare-metal server, a DigitalOcean Droplet, an AWS .metal instance, or another VM with nested virtualization enabled. A plain cloud VM without it won’t spawn sandboxes.

See Requirements for the full list of known-good instances, how to verify a host, sizing, and filesystem recommendations. In short: Linux x86_64, /dev/kvm, the tun module, and Docker (the installer handles TUN and Docker for you).

Install

curl -fsSL https://qbox.sh/install.sh | sh

The installer is idempotent and:

  1. Verifies the host (Linux, /dev/kvm, the tun module) and installs Docker if it isn’t present.
  2. Ensures the firecracker and jailer binaries are staged (downloads the pinned official release if missing).
  3. Downloads the guest kernel (vmlinux), the qboxd guest agent, and dropbear into ./assets.
  4. Downloads the latest docker-compose.yml.
  5. Generates a .env with strong random secrets on first run (it never overwrites an existing .env).
  6. Pulls the published images and brings the stack up.

When it finishes, open the URL it prints and complete the install flow to create the first admin user.

Override defaults with environment variables, e.g.:

curl -fsSL https://qbox.sh/install.sh | QBOX_SITE_ADDRESS=qbox.acme.com QBOX_DATA_DIR=/mnt/data/qbox sh

HTTPS / TLS

TLS is handled by Caddy and driven by a single variable, QBOX_SITE_ADDRESS:

You setWhat happens
A real domain (qbox.acme.com)Automatic Let’s Encrypt certificate, auto-renewed.
An IP address or left as :443Caddy serves a self-signed cert from its internal CA.
QBOX_TLS_CERT + QBOX_TLS_KEYCaddy uses your certificate and key (mounted into the proxy).

Caddy listens on 443 and redirects 80 → 443. To bring your own cert, drop tls.crt and tls.key into the TLS directory (QBOX_TLS_DIR, default ./tls) and the proxy uses them automatically.

Point DNS first. Let’s Encrypt only issues a certificate once your domain already resolves to this host. Before (or right at) install, add an A/AAAA record for qbox.acme.com pointing at the host’s public IP, and make sure ports 80 and 443 are open to the internet. If you open the site and see a certificate error, DNS isn’t pointing here yet (or 80/443 is blocked) — fix that and Caddy obtains the cert within seconds, no restart needed.

Choosing where data lives

All persistent state lives under QBOX_DATA_DIR (default /var/lib/qbox): Postgres, NATS, object storage, the builder workspace, and the host-agent cache. Point it at a large, reflink-capable disk:

QBOX_DATA_DIR=/mnt/volume_xfs/qbox

The installer creates the subdirectories; changing it later means moving the data and updating .env.

Build your first template

  1. Templates → New in the dashboard. Give it a public image such as python:3.12. The builder pulls it, builds a rootfs, boots and snapshots a microVM, and uploads the artifacts. Wait for ready (watch the build log) — a build can take several minutes, and longer for a large image or on a slow disk.
  2. Sandboxes → Spawn: pick the template. It moves pending → booting → running.
  3. Use Logs and Files; if the template enabled SSH, the Shell tab opens an interactive session inside the VM.

Build & first-spawn cost. Building a template is CPU- and I/O-heavy — it pulls the image, builds an ext4 rootfs, and boots a microVM to snapshot it — so expect it to use real host CPU (size the host accordingly, and note QBOX_BUILDER_CONCURRENCY runs builds in parallel). A single build can take several minutes, and longer for a large image or on a slow disk. The first spawn of a freshly-built template also pulls its rootfs/snapshot/kernel from object storage into the host’s local cache, which can take several seconds for a large image; a spawn issued immediately after the build waits on that pull. Subsequent spawns are warm (served from cache).

Updating

Re-run the installer — it re-downloads the latest docker-compose.yml, pulls the new images, and recreates changed services. Your .env and data are left intact.

curl -fsSL https://qbox.sh/install.sh | sh

Or, in the install directory:

docker compose pull && docker compose up -d

Operating the stack

# follow logs
docker compose logs -f control-plane host-agent

# stop / start (keeps data)
docker compose down
docker compose up -d

# stop and DELETE all data
docker compose down -v

Adding capacity

The single-host stack runs one host agent on the same box. To add more capacity, run the host-agent image on additional KVM hosts pointed at the same NATS and object storage. See Configuration for the host-agent variables.

Note: because Firecracker processes are children of the host-agent container, restarting it stops running microVMs (their sandboxes are marked terminated). For VMs that survive agent restarts, run the host agent under systemd instead of Docker.