The stack reads configuration from a .env file next to docker-compose.yml.
The installer generates one with strong random secrets on first run, so a default
install needs no manual configuration. Override anything below by editing
.env (or passing the variable to the installer) and re-running
docker compose up -d.
Minimal to get started
On a default install these are auto-generated. Set them yourself only if you want
specific values:
| Variable | Default | Description |
|---|
QBOX_SITE_ADDRESS | :443 | Public address Caddy serves. A real domain enables automatic Let’s Encrypt; an IP or :443 uses a self-signed cert. |
QBOX_DATA_DIR | /var/lib/qbox | Host directory for all persistent data. Put it on an xfs/btrfs (reflink) disk. |
Secrets
Auto-generated by the installer; rotate by editing .env.
| Variable | Default | Description |
|---|
POSTGRES_PASSWORD | (random) | Postgres password. |
QBOX_SESSION_SECRET | (random) | Signs dashboard session cookies. openssl rand -hex 32. |
QBOX_S3_ACCESS_KEY | qboxadmin | Object-storage access key. |
QBOX_S3_SECRET_KEY | (random) | Object-storage secret key. |
Public access & TLS
| Variable | Default | Description |
|---|
QBOX_SITE_ADDRESS | :443 | See above. Domain → Let’s Encrypt (the domain must already point at this host’s public IP, with 80+443 open, or the cert won’t issue); IP/:443 → self-signed. |
QBOX_PUBLIC_URL | derived from QBOX_SITE_ADDRESS | Origin used for cookies + CORS, e.g. https://qbox.acme.com. |
QBOX_TLS_DIR | ./tls | Directory mounted into Caddy for a bring-your-own certificate. |
QBOX_TLS_CERT | (unset) | Path (inside the proxy) to your TLS certificate. Drop tls.crt in QBOX_TLS_DIR. |
QBOX_TLS_KEY | (unset) | Path to your TLS private key (tls.key in QBOX_TLS_DIR). |
QBOX_COOKIE_SECURE | true | Session cookies are HTTPS-only. Keep true behind Caddy. |
Sandboxes
| Variable | Default | Description |
|---|
QBOX_DEFAULT_SANDBOX_TIMEOUT_SECONDS | 300 | Auto-kill window (from spawn) when a spawn request omits timeoutSeconds. e2b parity; clients extend it via setTimeout, and an explicit 0 on spawn disables it. |
QBOX_HOST_RETENTION | 24h | Delete a host row silent (no heartbeat) for this long that holds no active sandboxes; it re-registers automatically if it returns. |
Images
| Variable | Default | Description |
|---|
QBOX_IMAGE_REPO | ghcr.io/utibeabasi6 | Registry/namespace for the qbox images. |
QBOX_VERSION | latest | Image tag to run. Pin a semver (e.g. 1.4.2, or a moving 1.4 / 1) for reproducible deploys; also baked into the host agent as its reported version. |
Storage & assets
| Variable | Default | Description |
|---|
ASSETS_DIR | ./assets | Host directory holding firecracker, jailer, vmlinux, qboxd, and dropbear. |
QBOX_S3_BUCKET | qbox-artifacts | Bucket for rootfs/snapshot/kernel artifacts. |
QBOX_KERNEL_SHA256 | (unset) | Optional pin: warn at startup if the staged vmlinux hash differs. The builder auto-detects and uploads the staged kernel, so you normally leave this empty. |
Database
| Variable | Default | Description |
|---|
POSTGRES_USER | qbox | Postgres user. |
POSTGRES_DB | qbox | Postgres database name. |
Host agent
| Variable | Default | Description |
|---|
QBOX_HA_LABEL | host-1 | Human label for this host in the dashboard. |
QBOX_HOST_GRPC_INSECURE | false | Data-plane (control plane ↔ host agent) runs without mTLS. In production this also requires QBOX_HOST_GRPC_INSECURE_ACK=true — otherwise the control plane and host agent refuse to start. The single-host installer sets both; keep 9100 and the SSH-proxy range (40000–49999) firewalled off the internet and the sandbox subnet. For multi-host, leave both false and provide mTLS certs. |
QBOX_HOST_GRPC_INSECURE_ACK | false | Explicit acknowledgment that lets insecure mode run in production on a single trusted host. Prevents accidentally exposing an unauthenticated data plane when scaling out. |
Sandbox resource caps
Per-sandbox cgroup limits on the host-side Firecracker process. Firecracker’s
guest sizing does not bound the host process, so these stop one untrusted
sandbox from starving the host.
| Variable | Default | Description |
|---|
QBOX_SANDBOX_CGROUP_LIMITS | true | Apply per-VM memory.max / cpu.max / pids.max via the jailer. Needs cgroup-v2 controllers delegated to the host agent — the compose runs it with cgroup: host for this. Set false if you run the agent without delegation (otherwise the jailer can’t start firecracker). |
QBOX_SANDBOX_MEM_HEADROOM_MB | 256 | Extra memory above the guest RAM allowed for Firecracker’s own overhead. |
QBOX_SANDBOX_PIDS_MAX | 2048 | PID backstop for the Firecracker process group. |
QBOX_SANDBOX_NET_ISOLATION | true | Each sandbox reaches only the internet — guest↔guest and guest→host traffic is dropped. On by default; set false only as an escape hatch. |
Builder
| Variable | Default | Description |
|---|
QBOX_BUILDER_CONCURRENCY | 2 | How many template builds run in parallel. |
QBOX_BUILDER_ROOTFS_FREE_MB | 512 | Writable free space added to each template’s rootfs above its image content, so sandboxes can write files. Sized at build time (a sandbox’s disk can’t grow at spawn). 0 = no headroom. |
QBOX_BUILDER_SNAPSHOT_BOOT_TIMEOUT | 6m | How long the builder waits for the guest’s qboxd READY handshake when snapshotting a template. Raise it if cold builds time out (qboxd_not_ready) on a slow disk; a failed attempt is retried automatically. |
Installer asset integrity
The installer verifies each downloaded guest asset against a checksum.
| Variable | Default | Description |
|---|
QBOX_ASSET_BASE_URL | https://assets.qbox.sh/latest | Where vmlinux/qboxd/dropbear (and their .sha256 sidecars) are fetched from — a CDN in front of the qbox asset store. Override to pin a version (…/v1.2.3) or use your own mirror. |
QBOX_ASSET_VERIFY | true | Verify each asset against its sibling <name>.sha256. Disable only on a trusted dev box. |
QBOX_FIRECRACKER_SHA256 | (unset) | Pin the Firecracker release tarball’s SHA-256. Unset → downloaded over HTTPS but not checksum-verified (a warning prints). |
Tips
- After editing
.env, apply with docker compose up -d (recreates only what changed).
- Swap the guest kernel by replacing
assets/vmlinux and restarting the builder:
docker compose up -d --force-recreate builder. Rebuild templates to adopt it
(a Firecracker snapshot can’t resume on a different kernel).