The Master Agent provides machine-wide cloud reporting for Beacon. It runs independently of any project and sends heartbeats to BeaconInfra (or a self-hosted API-compatible backend), ensuring your device is always visible in the cloud dashboard.
Beacon has two complementary reporting mechanisms:
| Component | Scope | Purpose |
|---|---|---|
beacon start |
Machine-wide | Device heartbeats, machine health |
beacon monitor |
Per-project | Project health checks, logs, metrics |
The master agent is ideal when you want:
- A single heartbeat for the entire machine (not tied to any project)
- Device visibility even when no projects are running
- Separation of machine health from project health
beacon init does not perform network requests.
Local-first (no API key yet):
beacon init --name my-homelab-serverBeaconInfra API key (from Settings → API Keys), after local setup:
beacon cloud login
# or non-interactive:
beacon cloud login --api-key "usr_your_api_key" --name my-homelab-serverThe API base URL is compiled into the binary and cannot be overridden at runtime (security: prevents attackers from redirecting heartbeats). Use beacon config show to see the baked-in URL. Self-hosted users must build from source with -ldflags "-X beacon/internal/cloud.DefaultBeaconInfraAPIURL=...".
Use beacon config show to print paths, device name, API base, and whether an API key is set.
To stop sending heartbeats and remove the stored key, run beacon cloud logout (sets cloud_reporting_enabled: false and clears api_key).
# Run in foreground (for testing)
beacon start
# Or use systemd (recommended)
systemctl --user start beacon-master.serviceCheck the systemd service status:
systemctl --user status beacon-master.service
journalctl --user -u beacon-master.service -fYour device should appear in the BeaconInfra dashboard.
After beacon init (local) and beacon cloud login (API key), the file typically looks like:
api_key: usr_your_api_key
device_name: my-homelab-server
heartbeat_interval: 30 # seconds
cloud_reporting_enabled: true
device_id: "" # populated after first successful heartbeat| Field | Description |
|---|---|
api_key |
User API key from BeaconInfra (starts with usr_) |
device_name |
Human-readable name for this device |
heartbeat_interval |
Seconds between heartbeats (default: 30) |
cloud_reporting_enabled |
Set to false to disable heartbeats |
device_id |
Auto-populated UUID after first heartbeat |
Note: The cloud API URL is compiled into the binary (
beacon config showprints it). It cannot be changed at runtime — this is a security measure to prevent attackers from redirecting traffic.
| Variable | Description |
|---|---|
BEACON_API_KEY |
User API key for beacon cloud login when not using --api-key |
BEACON_DEVICE_NAME |
Default device name when --name is omitted |
BEACON_HOME |
Override Beacon data directory (default ~/.beacon) |
When you run beacon bootstrap, it automatically:
- Creates
~/.beacon/config.yamlif it doesn't exist - Installs
beacon-master.serviceas a user systemd unit - Enables and starts the service
If you need to install manually:
# Create the service file
cat > ~/.config/systemd/user/beacon-master.service << 'EOF'
[Unit]
Description=Beacon Master Agent
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/beacon start
Restart=on-failure
RestartSec=30
[Install]
WantedBy=default.target
EOF
# Enable and start
systemctl --user daemon-reload
systemctl --user enable beacon-master.service
systemctl --user start beacon-master.service# Check status
systemctl --user status beacon-master.service
# View logs
journalctl --user -u beacon-master.service -f
# Restart after config changes
systemctl --user restart beacon-master.service
# Stop
systemctl --user stop beacon-master.serviceThe master agent sends the following data to POST /agent/heartbeat:
{
"hostname": "my-server",
"ip_address": "192.168.1.100",
"tags": ["beacon-master"],
"agent_version": "1.0.0",
"device_name": "my-homelab-server",
"os": "linux",
"arch": "amd64",
"metadata": {
"role": "beacon-master"
}
}The server responds with:
{
"device_id": "550e8400-e29b-41d4-a716-446655440000"
}The device_id is cached in ~/.beacon/config.yaml for subsequent requests.
You can run both beacon start and beacon monitor with heartbeats enabled:
| Scenario | master | monitor heartbeat | Use Case |
|---|---|---|---|
| Machine only | ✓ | - | Device visibility, no project monitoring |
| Project only | - | ✓ | Project health includes device heartbeat |
| Both | ✓ | ✓ | Separate machine/project health reporting |
- Large deployments: Machine health separate from application health
- Multiple projects: One machine heartbeat + multiple project monitors
- Redundancy: Backup heartbeat if monitor stops
For most single-project deployments, enabling report.heartbeat.enabled: true in your monitor.yml is sufficient. The monitor sends heartbeats with system metrics.
The authentication priority for API requests:
- UserConfig (
~/.beacon/config.yaml):api_keyfield - Agent Identity (
~/.beacon/config/agent.yml):device_tokenfield (legacy) - Monitor config:
report.tokenorreport.token_namefields
The beacon init command sets up option #1, which is the recommended approach.
Check if cloud reporting is enabled:
cat ~/.beacon/config.yaml | grep cloud_reporting_enabledVerify API key is set and check compiled cloud URL:
cat ~/.beacon/config.yaml | grep api_key
beacon config show | grep cloud_api_baseIf you see 401 Unauthorized:
- Verify your API key is correct
- Check the cloud URL includes
/apisuffix - Ensure the API key is a user key (starts with
usr_)
Check for configuration errors:
# Test manually
beacon start
# Check logs
journalctl --user -u beacon-master.service --no-pager -n 50- Check heartbeat is being sent (look for log output)
- Verify network connectivity to the cloud URL
- Ensure the device name is unique for your account
When you run beacon bootstrap:
beacon bootstrap myprojectThe bootstrap process:
- Prompts: "Send this host's health status to Beacon cloud?" (default: yes)
- Creates
~/.beacon/config.yamlwithcloud_reporting_enabled - If enabled, installs and starts
beacon-master.service
You can control this via bootstrap config file:
# beacon.bootstrap.yml
cloud_reporting_enabled: true # or false to skipOr skip interactively with --skip-systemd:
beacon bootstrap myproject --skip-systemdFor backward compatibility, Beacon still supports the legacy ~/.beacon/config/agent.yml file:
server_url: https://your-beacon-host.example/api
device_name: homelab-gateway
device_id: ""
device_token: "dtk_..." # device token (older auth method)The new ~/.beacon/config.yaml (created by beacon init) is preferred. If both exist, config.yaml takes precedence.
- README.md - Main documentation
- LOG_FORWARDING.md - Log forwarding configuration
- KEY_MANAGEMENT.md - API key management