Orb Configuration Guide
elide orb requires a PKL configuration file passed via --config. This page covers the patterns you will actually use: reverse proxy with auto-TLS, multi-service routing, Tailscale integration, admin API setup, and container deployments. For the exhaustive field-by-field schema, see the serve configuration reference.
elide orb --config server.pklThe file must amend elide:serve/ElideServer.pkl. Every field has a sensible default, so a minimal config only specifies what differs. CLI flags override the corresponding PKL values when both are provided.
---
Server blocks
Server blocks are the core organizational unit. They are keyed by domain, address, or label, and the key format determines default behavior:| Key format | Example | Inferred behavior |
|---|---|---|
Domain (contains .) | "api.example.com" | listen :443, domains { key }, auto-TLS |
Address (starts with : or host:port) | ":8080" | listen { key } |
| Label (anything else) | "main" | No inference; set listen and domains explicitly |
servers {
// Domain key — auto-TLS on :443 for api.example.com
["api.example.com"] {
handler = new ReverseProxy {
upstreams { "backend:8080" }
}
}
// Address key — listen on :9090, no TLS
[":9090"] {
handler = new Respond { status = 200; body = "ok" }
}
// Label key — explicit configuration
["internal"] {
listen { "10.0.0.1:443" }
domains { "internal.corp.example.com" }
handler = new StaticFiles { root = "./internal-docs" }
}
}Each server block supports: listen, domains, http3, handler, routes, proxy, tls, webrtc, and middleware.
---
Pattern: reverse proxy with auto-TLS
The most common orb deployment — terminate TLS with auto-provisioned certificates and proxy to backend servers.
amends "elide:serve/ElideServer.pkl"
tls {
acmeEmail = "ops@example.com"
}
servers {
["api.example.com"] {
routes {
new {
match { path = "/v1/**" }
handler = new ReverseProxy {
upstreams {
new { address = "backend-1:8080"; weight = 2 }
new { address = "backend-2:8080"; weight = 2 }
}
loadBalancing = "least_connections"
timeout = 15.s
}
}
}
handler = 404
}
}Because the server block key is a domain, Elide infers auto-TLS on port 443. The tls.acmeEmail is all ACME needs for HTTP-01 or TLS-ALPN-01 challenges.
Wildcard certificates with DNS-01
For wildcard certs or environments where port 80/443 are not externally reachable:
tls {
acmeEmail = "ops@example.com"
dnsChallenge {
provider = "cloudflare"
propagationTimeout = 120.s
pollInterval = 5.s
}
}Set CLOUDFLARE_API_TOKEN (and optionally CLOUDFLARE_ZONE_ID) in the environment. For custom providers, use provider = "webhook" with DNS_WEBHOOK_URL or DNS_WEBHOOK_SCRIPT.
CLI equivalent:
elide orb --config server.pkl --dns-challenge cloudflare --domain "*.example.com,example.com" --acme-email ops@example.comOn-demand TLS
Issue certificates at TLS-handshake time for hostnames not pre-provisioned in config. An authorization endpoint prevents abuse:
tls {
onDemand {
ask = "https://auth.internal/check-domain"
maxPerWindow = 10
burst = 5
window = 1.h
}
}Manual TLS and mTLS
tls {
auto = false
certFile = "/etc/ssl/server.pem"
keyFile = "/etc/ssl/server-key.pem"
minVersion = "1.3"
cipherSuites = "fips"
// Mutual TLS
clientAuth {
trustedCAs { "/etc/ssl/client-ca.pem" }
required = true
}
}Per-server-block TLS overrides are also supported:
servers {
["internal.example.com"] {
tls {
certFile = "/etc/ssl/internal.pem"
keyFile = "/etc/ssl/internal-key.pem"
clientAuth {
trustedCAs { "/etc/ssl/internal-ca.pem" }
required = true
}
}
}
}---
Pattern: multi-service with Tailscale and middleware
A typical production setup — SPA frontend, API proxy, Tailscale networking, admin API, and a middleware stack:
amends "elide:serve/ElideServer.pkl"
networks {
["corp"] {
tailscale { direct = true; authKey = env("TS_KEY") }
tunnel { bridgeInbound = true; bridgeOutbound = true }
}
}
admin {
enabled = true
listen = "unix:<<>>
}
servers {
[" app.example.com"] {
routes {
new {
match { path = "/api/**" }
handler = new ReverseProxy { upstreams { "api-service:3000" } }
}
}
handler = new StaticFiles { root = "./dist"; spaFallback = true }
middleware {
new Compress { algorithms { "zstd"; "br"; "gzip" } }
new RateLimit { requests = 100; window = 1.s }
new Cors { allowedOrigins { "https://app.example.com" } }
}
}
}---
Pattern: multi-network orchestration
Multiple overlay networks in a single process — a production tailnet, a WireGuard VPN to the office, and a staging tailnet pointed at Headscale:
amends "elide:serve/ElideServer.pkl"
networks {
["production"] {
tailscale {
direct = true
authKey = env("TS_PROD_KEY")
controlUrl = "https:<<>>
disco { heartbeatInterval = 2.s }
dataPlane { mtu = 1280; bufferPoolSize = 256 }
}
tunnel {
bridgeInbound = true
bridgeOutbound = true
listenPort = 443
}
}
[" office-vpn"] {
wireguard { configFile = "./wg-office.conf" }
tunnel { bridgeOutbound = true }
}
["staging"] {
tailscale {
direct = true
authKey = env("TS_STAGING_KEY")
controlUrl = "https://headscale.staging.example.com"
}
tunnel { bridgeInbound = true }
}
}Within a single network entry, tailscale and wireguard are mutually exclusive.
See Tailscale integration for detailed network configuration and tunnel bridging options.
---
Admin API
The admin API runs on an isolated listener, separate from the main serving pipeline.
Via PKL
admin {
enabled = true
listen = "tcp:127.0.0.1:9091"
token = env("ADMIN_TOKEN")
}Via CLI
elide orb --config server.pkl --admin-port 9091 --admin-token secretOn Unix, prefer a socket for local-only access:
elide orb --config server.pkl --admin-socket /var/run/elide/admin.sock--admin-socket takes precedence over --admin-port.
Endpoints
| Endpoint | Description |
|---|---|
GET / | Live HTMX dashboard |
GET /health | Health check (uptime, workers, server name) |
GET /ready | Readiness probe (200 when serving, 503 during drain) |
GET /config | Running configuration as JSON |
GET /routes | Compiled route table |
GET /middleware | Active middleware summary |
GET /listeners | Bound listener addresses and TLS modes |
GET /metrics | Runtime metrics |
GET /cache/stats | Per-root static file cache statistics |
POST /cache/purge | Purge all static file caches |
Global settings
global {
workers = 0 // 0 = auto-detect
maxConnections = 65536
shutdownTimeout = 30.s
serverName = "elide" // "" to suppress Server header
transport = "auto" // "auto" selects the best backend for your platform
keepalive = 75.s // idle connection timeout; 0.s to disable
dns {
// DNS resolver configuration
// Defaults to system resolv.conf settings
}
}Observability
observability {
traceContext = true // W3C Trace Context header parsing
serviceName = "my-service" // OpenTelemetry service name
samplingRate = 0.1 // sample 10% of traces
}Logging
logging {
level = "info" // "trace" | "debug" | "info" | "warn" | "error"
format = "json" // "json" | "text" | "pretty"
accessLog {
enabled = true
output = "stdout" // "stdout" | "stderr" | "/path/to/file"
}
}---
Pattern: container deployment
A minimal container deployment with standalone Tailscale, auto-HTTPS, and JSON logging:
elide orb \
--config /etc/elide/server.pkl \
--tailscale-direct \
--tailscale-auth-key "$TAILSCALE_AUTH_KEY" \
--auto-https \
--domain example.com \
--acme-email admin@example.com \
--no-tui \
--json---
CLI reference
elide orb [OPTIONS]| Flag | Default | Description |
|---|---|---|
-c, —config | none | PKL configuration file (required). |
—tailscale | false | Bind to Tailscale IP via local daemon. |
—funnel | false | Expose via Tailscale Funnel. Implies —tailscale. |
—tailscale-direct | false | Standalone Tailscale node. Requires —tailscale-auth-key. |
—tailscale-auth-key | none | Pre-auth key. Also reads TAILSCALE_AUTH_KEY. |
—tun | false | Create TUN device. Requires root or CAP_NET_ADMIN. |
—auto-https | none | Enable ACME. |
—domain | none | ACME domain(s), comma-separated. |
—acme-email | none | ACME contact email. |
—acme-staging | false | Use Let's Encrypt staging CA. |
—dns-challenge | none | DNS-01 provider: cloudflare or webhook. |
—derp | false | Co-host DERP relay. |
—derp-port | 3340 | DERP relay port. |
—admin-port | none | Admin API TCP port. |
—admin-host | 127.0.0.1 | Admin API bind address. |
—admin-socket | none | Admin API Unix socket. |
—admin-token | none | Admin API bearer token. |
—no-tui | false | Disable TUI. |
—json | false | JSON output. |
—claim-fds | false | Claim listener fds for zero-downtime upgrade (internal). |
—escrow-id | none | Sidecar escrow ID for connection transfer (internal). |
See also
elide orb— overview, capabilities, and quick deploy- Tailscale integration — daemon mode, standalone mode, Funnel, DERP, multi-network
- Serve configuration reference — complete PKL schema for handlers, routes, middleware