Setup walkthrough
From an empty server to a working tunnel — DNS, beamd init, serve, and your first developer. ~30–60 minutes, mostly waiting on DNS.
This is the guided path with a checkpoint at every step. It uses Cloudflare
for DNS (the supported provider) and Docker to run the edge. Cost is roughly
a domain ($10–15/yr) plus a small VM ($5/mo); everything else is free.
Pick your values up front:
| Placeholder | Meaning |
|---|---|
YOUR_DOMAIN | The hostname Beamd lives under (its base_domain) — e.g. beam.example.com |
YOUR_SERVER_IP | Public IPv4 of the VM you'll run Beamd on |
YOUR_EMAIL | Contact email for Let's Encrypt |
YOUR_CF_TOKEN | The Cloudflare API token from step 2 |
1. Point your domain at Cloudflare
Add YOUR_DOMAIN (or its parent zone) as a site in Cloudflare on the Free plan,
and set your registrar's nameservers to the two Cloudflare gives you. Verify:
dig NS YOUR_DOMAIN +short # returns the Cloudflare nameservers2. Create a Cloudflare API token
Cloudflare → My Profile → API Tokens → Create Token → "Edit zone DNS", scoped
to your zone. Copy it (shown once) — this is YOUR_CF_TOKEN. Verify:
curl -s -H "Authorization: Bearer YOUR_CF_TOKEN" \
https://api.cloudflare.com/client/v4/user/tokens/verify
# → "success":true3. Point the domain at your server
Rent any Linux VM with a public IPv4 (Hetzner, DigitalOcean, Linode, Vultr…), then add one DNS record in Cloudflare:
| Field | Value |
|---|---|
| Type | A |
| Name | @ for an apex domain, or the subdomain label (e.g. beam) |
| IPv4 | YOUR_SERVER_IP |
| Proxy status | DNS only (gray cloud) |
🚨 The record must be "DNS only" (gray cloud). If it's "Proxied" (orange), Cloudflare terminates TLS itself and Beamd's wildcard certs stop working.
dig YOUR_DOMAIN +short # returns YOUR_SERVER_IP4. Install Docker and generate the config
SSH into the server, install Docker, and run the one-shot interactive setup:
curl -fsSL https://get.docker.com | sh
docker run --rm -it \
-v /etc/beamd:/etc/beamd \
-v /var/lib/beamd:/var/lib/beamd \
ghcr.io/dynamismlabs/beamd:latest initinit prompts for base_domain, edge_ipv4, acme_email, etc. and writes
/etc/beamd/beamd.yaml, an empty /etc/beamd/tokens.json, and the data dir.
Every field is documented in the Configuration reference.
5. Run the edge
Drop the bundled docker-compose.yml into /etc/beamd/, put your Cloudflare
token in /etc/beamd/.env, and start it:
echo "BEAMD_DNS_PROVIDER_CREDS=YOUR_CF_TOKEN" | sudo tee /etc/beamd/.env
sudo chmod 600 /etc/beamd/.env
cd /etc/beamd && sudo docker compose up -d
sudo docker compose logs beamd # → INFO ready ... listen_https=:443A quick reachability check (cert verification fails until step 6 issues one — that's expected):
curl -k https://YOUR_DOMAIN/healthz # → {"status":"ok","version":"…"}Running it as a binary + systemd instead of Docker? See Production.
6. Add yourself as a developer
One command mints a token, writes the wildcard DNS, and pre-issues your cert:
sudo docker compose exec beamd beamd add-developer --config /etc/beamd/beamd.yamlIt prints a token (copy it — shown once) and a flat routing line: tunnels at
<name>.YOUR_DOMAIN. Restart so the new token loads:
sudo docker compose restart beamdSharing the edge with others who shouldn't collide on names? Add --slug — see
Onboarding developers.
7. Connect from your laptop and test
npm i -g @beamd/cli
beamd login --server YOUR_DOMAIN --token <token from step 6>
python3 -m http.server 3001 # any local server
beamd open 3001 --as hello # → https://hello.YOUR_DOMAINOpen https://hello.YOUR_DOMAIN in a browser — directory listing, real
Let's Encrypt cert, no warnings. That's a working edge. 🎉
If anything misbehaved, see Troubleshooting.