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.
bash
 elide orb --config server.pkl

The 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 formatExampleInferred 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
pkl
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.

pkl
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:

pkl
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:

bash
 elide orb --config server.pkl --dns-challenge cloudflare --domain "*.example.com,example.com" --acme-email ops@example.com

On-demand TLS

Issue certificates at TLS-handshake time for hostnames not pre-provisioned in config. An authorization endpoint prevents abuse:

pkl
tls {
  onDemand {
    ask = "https://auth.internal/check-domain"
    maxPerWindow = 10
    burst = 5
    window = 1.h
  }
}

Manual TLS and mTLS

pkl
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:

pkl
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:

pkl
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:

pkl
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

pkl
admin {
  enabled = true
  listen = "tcp:127.0.0.1:9091"
  token = env("ADMIN_TOKEN")
}

Via CLI

bash
 elide orb --config server.pkl --admin-port 9091 --admin-token secret

On Unix, prefer a socket for local-only access:

bash
 elide orb --config server.pkl --admin-socket /var/run/elide/admin.sock
--admin-socket takes precedence over --admin-port.

Endpoints

EndpointDescription
GET /Live HTMX dashboard
GET /healthHealth check (uptime, workers, server name)
GET /readyReadiness probe (200 when serving, 503 during drain)
GET /configRunning configuration as JSON
GET /routesCompiled route table
GET /middlewareActive middleware summary
GET /listenersBound listener addresses and TLS modes
GET /metricsRuntime metrics
GET /cache/statsPer-root static file cache statistics
POST /cache/purgePurge all static file caches
---

Global settings

pkl
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

pkl
observability {
  traceContext = true          // W3C Trace Context header parsing
  serviceName = "my-service"   // OpenTelemetry service name
  samplingRate = 0.1           // sample 10% of traces
}

Logging

pkl
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:

bash
 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]
FlagDefaultDescription
-c, —confignonePKL configuration file (required).
—tailscalefalseBind to Tailscale IP via local daemon.
—funnelfalseExpose via Tailscale Funnel. Implies —tailscale.
—tailscale-directfalseStandalone Tailscale node. Requires —tailscale-auth-key.
—tailscale-auth-keynonePre-auth key. Also reads TAILSCALE_AUTH_KEY.
—tunfalseCreate TUN device. Requires root or CAP_NET_ADMIN.
—auto-httpsnoneEnable ACME.
—domainnoneACME domain(s), comma-separated.
—acme-emailnoneACME contact email.
—acme-stagingfalseUse Let's Encrypt staging CA.
—dns-challengenoneDNS-01 provider: cloudflare or webhook.
—derpfalseCo-host DERP relay.
—derp-port3340DERP relay port.
—admin-portnoneAdmin API TCP port.
—admin-host127.0.0.1Admin API bind address.
—admin-socketnoneAdmin API Unix socket.
—admin-tokennoneAdmin API bearer token.
—no-tuifalseDisable TUI.
—jsonfalseJSON output.
—claim-fdsfalseClaim listener fds for zero-downtime upgrade (internal).
—escrow-idnoneSidecar escrow ID for connection transfer (internal).
---

See also