Documents how to wire beszel-agent into any flake build: the two-module split (enable-agent.nix in build types, host-token.nix in host files), sops secret creation, hub pairing flow, and optional EXTRA_FILESYSTEMS / Docker monitoring knobs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5.4 KiB
Beszel agent
Beszel is the monitoring dashboard used
in this LAN. The hub runs as a Docker container on docker.sweet.home (port
vars.ports.beszelHub, 8090). Each monitored NixOS host runs a
beszel-agent that connects back to the hub.
This document explains how to wire beszel-agent into any build in the flake.
How it is split across modules
There are two modules and they have separate jobs:
| Module | What it does | Where it goes |
|---|---|---|
modules/beszel/enable-agent.nix |
Enables the systemd service, sets HUB_URL, fixes upstream StateDirectory bug |
Build type (modules/build-types/*.nix) |
modules/beszel/host-token.nix |
Declares the sops secret + env-file template that holds TOKEN |
Host file (hosts/<name>/host.nix) |
KEY (the hub's public key for this agent slot) is a plain string set
directly on the host under services.beszel.agent.environment.KEY — it comes
from the hub UI, not from sops, so it belongs in the host file rather than a
secret.
Adding beszel to a new build type
Open modules/build-types/<type>.nix and add ../beszel/enable-agent.nix to
the imports list:
imports = [
../beszel/enable-agent.nix
# ... other imports
];
That is the only change needed at the build-type level. The module sets:
services.beszel.agent.enable = trueHUB_URLpointing atdocker.sweet.home:8090- a persistent
StateDirectoryfor the hub-pairing fingerprint
Wiring the host file
Every host whose build type includes enable-agent.nix needs two things in
its hosts/<name>/host.nix:
1 — Import host-token.nix
imports = [
(import ../../modules/beszel/host-token.nix {
name = "<hostname>"; # must match the sops secret file name below
sopsFile = ../../secrets/<hostname>.yaml;
})
];
This creates a sops-managed env file at runtime containing TOKEN=<value> and
passes it to the agent via environmentFile. The name argument also becomes
the sops template name (<name>-beszel.env), so it must be unique per host.
2 — Set KEY once the hub has paired the agent
services.beszel.agent.environment = {
KEY = "ssh-ed25519 AAAA...";
};
KEY is the hub's SSH public key for this agent slot — copy it from the hub
UI after the agent first connects (see "Pairing with the hub" below).
Until the hub has been paired, leave KEY commented out or omit it. The agent
will still start and appear in the hub as an unpaired entry; fill in the key
after that first connection.
Adding the sops secret
The beszel-token value in secrets/<hostname>.yaml is the token the agent
uses to authenticate to the hub. To add it for a new host:
- Decrypt and edit the host's secrets file:
sops secrets/<hostname>.yaml - Add the token:
beszel-token: <token from the beszel hub UI> - Save and close — sops re-encrypts the file on exit.
If the host does not yet have a secrets/<hostname>.yaml, create one using
the same sops recipients as the other secrets files (check .sops.yaml), or
run scripts/secrets/sync-host-keys.sh <target> first so the host's own
SSH key is already a valid recipient.
The token is found in the beszel hub under Settings → Keys or when you add a new system via the hub UI.
Optional: monitoring extra filesystems
To have the agent report disk usage for a mount point that is not the root
filesystem, add EXTRA_FILESYSTEMS in the host file alongside KEY:
services.beszel.agent.environment = {
KEY = "ssh-ed25519 AAAA...";
EXTRA_FILESYSTEMS = "/mnt/data"; # colon-separated if more than one
};
The server host uses this to expose the ZFS data pool:
EXTRA_FILESYSTEMS = "${vars.storageRoot}/${vars.nfsShares.dockerVolumes.subpath}";
Optional: monitoring Docker containers
The enable-agent.nix module has a commented-out line for Docker monitoring:
#DOCKER_HOST = "tcp://docker-socket-proxy:2375";
Uncomment it if the host runs docker-socket-proxy and you want per-container stats in the hub. Hosts that do not run Docker should leave this commented out.
Pairing with the hub
- Deploy the host with
host-token.niximported andenable-agent.nixpresent in the build type. LeaveKEYunset for now. - Open the beszel hub (
http://docker.sweet.home:8090). - Go to Systems → Add system. The new host should appear as an
unpaired entry — copy the
KEYvalue shown there. - In
hosts/<name>/host.nix, set:services.beszel.agent.environment.KEY = "<copied key>"; - Rebuild and deploy the host. The agent will now pair permanently with the hub.
Example: complete host file
For reference, hosts/tor-relay/host.nix is the minimal case — one
filesystem, no Docker, LXC platform:
{ vars, ... }:
{
imports = [
(import ../../modules/beszel/host-token.nix {
name = "tor-relay";
sopsFile = ../../secrets/tor-relay.yaml;
})
];
networking = { ... };
services.beszel.agent.environment = {
KEY = "ssh-ed25519 AAAA...";
};
system.stateVersion = "26.05";
}
hosts/server/host.nix is the fuller case — extra filesystem path, debug
logging:
services.beszel.agent.environment = {
KEY = "ssh-ed25519 AAAA...";
EXTRA_FILESYSTEMS = "${vars.storageRoot}/${vars.nfsShares.dockerVolumes.subpath}";
LOG_LEVEL = "debug";
};