On a server
This guide takes you from a bare Linux machine to the parts of Beacon that live on servers: at the end, the centre runs on one machine with you as its owner, two probe locations check your services, and one server is enrolled as a machine agents may work on through Beacon. Connecting your agent and rehearsing an outage have their own pages, linked from steps 4 and 5. It is written for someone who runs a few servers, has root on a machine with Docker, and uses an agent on a workstation. To see the whole loop before you commit a server, try it on your laptop first.
Each step says how long it takes, what to run, what you should see, and what to do when you see something else. Commands on the centre run from /opt/beacon, through docker exec beacon beacon ….
| Step | Time |
|---|---|
| 0. What you need | not counted: a machine, two DNS names |
| 1. Install the centre | 3 minutes, of which the script runs for 1 to 2 |
| 2. The first probe | 5 minutes for two locations |
| 3. The first machine | 4 minutes |
| 4. The first agent | 5 minutes, in Try it on your laptop |
| 5. The first drill | 10 minutes, in Rehearse an outage |
Steps 1 to 3 take about 12 minutes once step 0 is done. DNS propagation is outside your hands, and outside the count.
0. What you need
Three words first. The centre is the machine Beacon runs on. A probe location is a small machine somewhere your users are, running beacon-probe, which checks your services every minute and sends the results to the centre. A machine is a server agents may work on through Beacon.
- The centre: Linux with 2 CPUs, 4 GB of memory and 40 GB of disk; Docker Engine with Docker Compose v2; the OpenSSH client (
ssh-keygen). - Two DNS names pointing at the centre: one for people and agents (
status.example.combelow: the API, MCP, the console, the status page, and the SSH channel on port 17002) and one for machines (metrics.example.com: the gateway the probes report to). Ports 80 and 443 must be reachable from the Internet, for Let's Encrypt and for the traffic; port 17002 from wherever your agents run. - An e-mail address Let's Encrypt can write to about the certificates. It must be a real one: the installer refuses
example.comaddresses. - A small machine for the first probe location: any Linux with systemd, on x86_64 or arm64, with 64 MB of memory to spare. A VPS where your users are is best. The centre itself will do for the second location.
- A machine agents may work on, which the centre can reach on its SSH port. The probe machine will do.
- An agent on a workstation with a browser, to sign it in (step 4).
1. Install the centre
3 minutes. On the centre, fetch the reference deployment and look at the release it names:
git clone https://github.com/openlinkos/beacon.git
sudo cp -r beacon/deploy /opt/beacon && cd /opt/beacon
grep BEACON_VERSION .env.exampleBEACON_VERSION is the release Beacon will run; the installer copies .env.example to .env on its first run. If it is not the latest release, change it in .env.example now. Later, to update, change it in .env and run the installer again, which is safe at any time. Then run it:
sudo ./install.shThe script asks for the two host names and the e-mail address. To run it unattended, give them in the environment: STATUS_HOST=… METRICS_HOST=… ACME_EMAIL=… sudo ./install.sh. It then copies .env.example to .env, generates the secrets (the token the rule engine uses, and the SSH channel's host and CA keys, which never leave the machine), puts your names into config.yaml and the probe targets, validates every file with its own image, pulls the four images (Beacon, VictoriaMetrics, vmalert and Caddy), starts them, and waits until all four are healthy and the rule engine's first alert has reached Beacon. It took 69 seconds on a well-connected host; allow one to two minutes on a 2-CPU machine with ordinary bandwidth, most of it pulling images.
You should see it end like this:
configuration OK: Feishu app false, Pushover false, Bark false; gateway ":17006"; SSH channel :17002; 0 agent hooks
files: 1 probe locations, 0 heartbeats, 0 resources, 3 probe targets in 2 sets, 5 modules, 1 status pages
database: none yet at /var/lib/beacon/status.db; the service imports the files when it first starts
Waiting for the containers to be healthy …
Beacon is up (69s); made the secrets: rules-token ssh-host-key ssh-ca-key.
https://status.example.com the API (/api/v1), MCP (/mcp) and pages; the first certificate takes about a minute
https://metrics.example.com the gateway for machines
status.example.com:17002 the SSH channelfollowed by the next steps, which are the steps of this guide. Then check both host names from anywhere:
curl https://status.example.com/healthz # ok
curl https://metrics.example.com/api/v1/targets # {"code":"auth.required",…}: refused without a token, as it should beOpen https://status.example.com/ in a browser: it is the example status page from catalog/status_pages.yaml, saying No data yet until the probes report. Nobody is notified of anything yet: without a chat configured, alerts are recorded and shown in the API, MCP and the console, which is all the next steps need.
If it does not go like this:
install.sh: …and it stops: the message says what is missing (root, Docker, Compose v2,ssh-keygen, a real e-mail address, two different host names) or which file does not validate, with the command that shows why.curlfails on TLS: the first certificate takes up to a minute after the start. If it still fails, check that both names resolve to the centre and that ports 80 and 443 are open;docker compose logs caddysays what Let's Encrypt answered.
deploy/README.md says where each file of the deployment is.
2. The first probe
5 minutes for two locations. Beacon tells an outage from a hiccup by agreement: a service is down only when at least two locations fail it, and they are at least half of the locations reporting. So the first location gives you data, and the second gives you alerts.
The first location. The catalogue (catalog/locations.yaml, imported into Beacon's database at the first start) already holds one location, edge-1. On the centre, enrol it. The token is printed once:
docker exec beacon beacon enroll probe edge-1 > edge-1.tokenYou should see enrolled probe-edge-1 (probe:write, expires …); the token above is not shown again, and edge-1.token holds a line starting with lbt_. Copy /opt/beacon/probe/ and edge-1.token to the probe machine and run there, as root:
sh probe/install.sh -gateway https://metrics.example.com -token-file edge-1.tokenAbout 10 seconds later it ends with:
edge-1: beacon-probe beacon 0.3.0-rc.15 …; installed: token agent.env beacon-probe beacon-probe.service beacon-heartbeat; 13 MB resident
the gateway at https://metrics.example.com accepted the first push; the location's results arrive every minuteFrom then on the location probes every minute whatever the gateway hands it, so changing what is checked never means touching the probe again.
The second location. It can be the centre itself (nearly free) or another small machine. Add it to the catalogue file, /opt/beacon/catalog/locations.yaml on the centre, below edge-1:
- id: edge-2
name: Germany - Frankfurt # public: name places and networks, never vendors
region: overseas
network: BGPImport the files into Beacon, first to see what would change, then for real, and enrol the new location:
docker exec beacon beacon config import /etc/beacon -dry-run
docker exec beacon beacon config import /etc/beacon -note "second probe location"
docker exec beacon beacon enroll probe edge-2 > edge-2.tokenThe dry run should list one line, + locations edge-2, under would change 1 items (nothing changed):, and the import the same under version 2: import of 1 items. Then install the probe as above on the second machine. On the centre itself, point it at the gateway's own port, which the reference deployment publishes on 127.0.0.1:
sudo sh probe/install.sh -gateway http://127.0.0.1:17006 -token-file edge-2.tokenAn import makes the files the whole configuration: anything changed through the API or MCP that the files do not hold is removed, which is why -dry-run comes first. What is checked, and from where explains the two ways of changing the configuration and how to keep them in step; Probe locations has where to put them, what the machine needs, and what to do when the install does not end like the above.
Check what arrives. VictoriaMetrics' own UI is on the centre at http://127.0.0.1:8428/vmui (from your workstation through ssh -N -L 8428:127.0.0.1:8428 centre). probe_success has one series per location and target, 1 for success. The public page at https://status.example.com/ now shows its components' state. The targets shipped are Beacon's own status host, the drill (step 5) and https://example.com/; replace the last with a service of yours in /opt/beacon/targets/all-web.yaml and import again.
3. The first machine
4 minutes. A machine agents will work on. On the centre:
docker exec beacon beacon machine add edge-1 edge-1.example.net -note "the first probe machine"Beacon connects once, pins the machine's host key (it will refuse any other key for this machine from now on), and prints what the machine needs:
added edge-1 at edge-1.example.net:22 as beacon; its host key is SHA256:…
On the machine, as root, if not done yet:
echo 'ssh-ed25519 AAAA… beacon-ca' > /etc/ssh/beacon_ca.pub
echo 'TrustedUserCAKeys /etc/ssh/beacon_ca.pub' > /etc/ssh/sshd_config.d/beacon.conf
id beacon >/dev/null 2>&1 || useradd -m -s /bin/bash -p '*' beacon
systemctl reload ssh
(see docs/guide/machines.md for sudo and for PerSourcePenaltyExemptList)Run those four lines on the machine, as root. They make sshd trust Beacon's certificate authority (CA), the key that signs a short-lived certificate for each connection, and create the account those certificates name. If machine add fails with the machine cannot be reached, the centre cannot open a connection to the machine's SSH port: allow it in the machine's firewall, or, for a machine behind NAT, add it the other way round as Machines behind NAT describes.
Two more settings are worth making now rather than later:
- What the
beaconaccount may do is the real boundary. Give it only what the work needs, for example in/etc/sudoers.d/beacon:beacon ALL=(root) NOPASSWD: /usr/bin/systemctl restart beacon-probe, /usr/bin/journalctl. - Exempt the centre from OpenSSH's penalties for failed connections: every agent arrives from the centre's address, so add
PerSourcePenaltyExemptList 203.0.113.7(the centre's address) tobeacon.conf.
Give agents a machine has the rest.
4. The first agent
5 minutes, and every step of it is written out in Try it on your laptop: the same commands against your server. In short, make the first account with the one-time link the service prints, then connect your agent over MCP and sign it in through the browser:
docker exec beacon beacon setup
claude mcp add --scope user --transport http beacon https://status.example.com/mcpThe agent never does more than your role allows, and every command it runs on a machine is on record with a replay. Roles, Codex, invitations and headless agents with tokens are in People and their agents.
5. The first drill
10 minutes, most of it waiting, written out in Rehearse an outage. In short, Beacon has a service of its own to rehearse on; with two locations, docker exec beacon beacon drill fail 15m makes both locations fail, ServiceDown fires about 4 to 5 minutes later, and beacon drill off ends it and the alert resolves at once.
What next
- Set up the Feishu app, so alerts reach people as cards. Each secret goes in a file under
/opt/beacon/secrets/, thefeishu:section in/opt/beacon/config.yamlis uncommented, andsudo ./install.shfollowed bydocker compose restart beaconapplies it (Configuration). - Put an agent on call, so a new alert wakes an agent instead of waiting for someone to ask.
- Upgrades, Backup and restore and Security model keep it running.
- Troubleshooting for when something above does not happen.
- Goals: what Beacon is for, and what it will not do.