app-lb
A Pingora-based load balancer that boots Firecracker microVMs on demand: requests route by hostname and path, cold starts hold the request while a VM boots, and idle pools scale to zero.
app-lb is one binary with two listeners:
- The proxy (
0.0.0.0:6188, TLS on:6189) — the data plane. Every request is routed to a deployment: a pool of managed microVMs, a fixed set of upstream addresses, or a directory of files served straight off disk. - The admin API (
127.0.0.1:9090) — the control plane: register deployments, watch the dashboard, mint tokens, runexecandshellinside VMs. Loopback and plaintext by design; reach a remote one over an SSH tunnel or through the proxy itself.
DeploymentsThe spec, the three backend
kinds, routing rules, and how autoscaling and cold starts work.
Auth & tokensSign-in gates in front of
deployments, app-tokens for programs, and the admin API's two tiers.
NamespacesSegregate deployments and walk
tokens into exactly one room.
Event feedPer-namespace RSS of deploys and
operational trouble — strictly opt-in.
serverctlThe CLI: contexts, specs, scaling,
exec/shell, tokens and feeds.
Quick start
# start app-lb (it finds the heyvm daemon on the host)
app-lb
# register a deployment from a spec file
serverctl apply -f web.json
# watch it
serverctl get deployments
serverctl describe web
A minimal managed deployment:
{
"id": "web",
"routes": [ { "host": "web.example.com" } ],
"vm": { "driver": "firecracker", "image": "web-rootfs", "port": 8080 },
"scaling": { "min_replicas": 0, "max_replicas": 3 }
}
With min_replicas: 0 the pool sits empty until a request arrives; the proxy
holds the request (up to cold_start_timeout_secs, default 120) while the
autoscaler boots a VM, then completes it. After
scale_to_zero_after_secs (default 300) of idleness the pool drains back to
zero.
One thing to internalise early: if a deployment declares an
auth gate, the gate runs before the cold-start wait. An
unauthenticated request never boots a VM — a browser that completes sign-in wakes the
deployment, an API client with no accepted credential gets an immediate 401 and wakes
nothing. See Auth & tokens.
Configuration
Everything is environment variables; nothing is required to start.
| Variable | Default | What it does |
|---|---|---|
APP_LB_PROXY_ADDR | 0.0.0.0:6188 | Data-plane listener. |
APP_LB_PROXY_TLS_ADDR | 0.0.0.0:6189 | TLS listener (with certs or ACME). |
APP_LB_ADMIN_ADDR | 127.0.0.1:9090 | Admin API and dashboard. |
APP_LB_STATE_PATH | app-lb-state.json | Where deployment specs persist (a .d/ directory beside it, one JSON file per deployment). |
APP_LB_TOKENS_PATH | app-lb-tokens.json | The app-token store, written 0600. Only secret hashes are kept. |
APP_LB_DASHBOARD_PASSWORD | unset | Setting it turns the admin gate on (user defaults to admin). |
APP_LB_ADMIN_AUTH | 0 | 1 extends the gate to the CRUD routes, not just the dashboard. |
APP_LB_ACME_EMAIL | unset | Setting it turns on automatic certificates for routed hostnames. |
APP_LB_OBS_URL | unset | Ship logs, access records and stats to an app-obs instance. |
APP_LB_SIEM | 1 | The built-in security analyzer; 0 disables detection (block rules keep working). |