Configuration
Every beamd.yaml field, what it does, and the BEAMD_* environment-variable override convention.
The edge reads a single YAML file — /etc/beamd/beamd.yaml by default, or pass
--config <path>. beamd init writes a starting one for you; this page is the
full reference.
beamd.yaml fields
| Field | Required | Notes |
|---|---|---|
base_domain | yes | The hostname tunnels live under, e.g. beam.example.com. |
edge_ipv4 | for provision-dev | This server's public IPv4 (written into DNS). |
edge_ipv6 | no | Optional IPv6 target. |
listen_https | yes | Public ingress + ALPN-demuxed client control. :443 in prod, :8443 in dev. |
acme_email | yes | Contact address registered with Let's Encrypt. |
acme_ca | no | ACME directory URL. Blank = LE production; off = self-signed (dev only). |
dns_provider | yes | cloudflare or stub (in-memory, for tests). See DNS providers. |
dns_provider_creds | provider-specific | Cloudflare: a Zone:DNS:Edit API token. Better set via env (below). |
dns_zone | no | Registered zone to write records in. Blank = auto-detect from base_domain (recommended). |
token_store | yes | file:<path> (a JSON {token: slug} map) or memory: for tests. |
data_dir | no | Where Beamd persists state (cert cache, ACME account, bandwidth totals). Default /var/lib/beamd. |
max_tunnels_per_token | no | Concurrent-tunnel cap per credential. Default 25. |
max_request_body_bytes | no | Per-request public body cap; oversized → HTTP 413. Default 32 MiB (33554432); -1 disables. |
preview_embed | no | Strip X-Frame-Options + CSP frame-ancestors so previews embed cross-origin in an iframe. Default false. See Security. |
A hosted deployment also configures device-code login discovery and a usage
webhook; those blocks are omitted on a self-hosted edge (the CLI then requires
--token, and you read /metrics instead of pushing usage).
Environment overrides
Every field can be overridden by a matching BEAMD_<UPPER_SNAKE_CASE>
environment variable. This is the right place for secrets — keep them out of the
YAML on disk:
BEAMD_DNS_PROVIDER_CREDS=<your-Cloudflare-API-token>
BEAMD_BASE_DOMAIN=beam.example.com # overrides base_domainBEAMD_DNS_PROVIDER_CREDS is the one you'll almost always set this way (the
docker-compose.yml reads it from /etc/beamd/.env).
A minimal example
base_domain: beam.example.com
edge_ipv4: 203.0.113.10
listen_https: ":443"
acme_email: ops@example.com
dns_provider: cloudflare
dns_provider_creds: "" # set via BEAMD_DNS_PROVIDER_CREDS instead
token_store: "file:/etc/beamd/tokens.json"
data_dir: /var/lib/beamd
max_tunnels_per_token: 25