A lightweight server resource monitoring hub with historical data, docker stats, and alerts.
- Lightweight: Smaller and less resource-intensive than leading solutions.
- Docker stats: Tracks CPU and memory usage history for each container.
- Alerts: Configurable alerts for CPU, memory, disk usage, and system status.
- Multi-user: Each user manages their own systems. Admins can share systems across users.
- Simple: Easy setup, no need for public internet exposure.
- OAuth / OIDC: Supports multiple OAuth2 providers. Password authentication can be disabled.
- Automatic backups: Save and restore data from disk or S3-compatible storage.
- REST API: Integrate your metrics into your own scripts and applications.
Beszel consists of two main components: the hub and the agent.
-
Hub: A web application that provides a dashboard for viewing and managing connected systems. Built on PocketBase.
-
Agent: Runs on each system you want to monitor, creating a minimal SSH server to communicate system metrics to the hub.
If not using docker, skip steps 4-5 and run the agent using the binary.
- Start the hub (see installation).
- Open http://localhost:8090 and create an admin user.
- Click "Add system." Enter the name and host of the system you want to monitor.
- Click "Copy docker compose" to copy the agent's docker-compose.yml file to your clipboard.
- On the agent system, create the compose file and run
docker compose up
to start the agent. - Back in the hub, click the "Add system" button in the dialog to finish adding the system.
If all goes well, the system should flip to green. If it turns red, check the Logs page and refer to troubleshooting tips.
Pour le tutoriel en français, consultez https://belginux.com/installer-beszel-avec-docker/
You can install the hub and agent as single binaries or using Docker.
Hub: See the example docker-compose.yml file.
Agent: The hub provides compose content for the agent, but you can also reference the example docker-compose.yml file.
The agent uses host network mode to access network interface stats, which automatically exposes the port. Change the port using an environment variable if needed.
If you don't require network stats, remove that line from the compose file and map the port manually.
Note: If disk I/O stats are missing or incorrect, try using the
FILESYSTEM
environment variable (instructions here). Check agent logs to see the current device being used.
Tip
If using Linux, see guides/systemd.md for a script to install the hub or agent as a system service. The agent installer will be built into the web UI in the future.
Download and run the latest binaries from the releases page or use the commands below.
curl -sL "https://github.com/henrygd/beszel/releases/latest/download/beszel_$(uname -s)_$(uname -m | sed 's/x86_64/amd64/' | sed 's/armv7l/arm/' | sed 's/aarch64/arm64/').tar.gz" | tar -xz -O beszel | tee ./beszel >/dev/null && chmod +x beszel && ls beszel
Running the hub directly:
./beszel serve
curl -sL "https://github.com/henrygd/beszel/releases/latest/download/beszel-agent_$(uname -s)_$(uname -m | sed 's/x86_64/amd64/' | sed 's/armv7l/arm/' | sed 's/aarch64/arm64/').tar.gz" | tar -xz -O beszel-agent | tee ./beszel-agent >/dev/null && chmod +x beszel-agent && ls beszel-agent
Running the agent directly:
PORT=45876 KEY="{PASTE_YOUR_KEY}" ./beszel-agent
Use ./beszel update
and ./beszel-agent update
to update to the latest version.
Name | Default | Description |
---|---|---|
DISABLE_PASSWORD_AUTH |
false | Disables password authentication |
Name | Default | Description |
---|---|---|
DOCKER_HOST |
unset | Overrides the docker host (docker.sock) if using a proxy.1 |
EXTRA_FILESYSTEMS |
unset | See Monitoring additional disks / partitions |
FILESYSTEM |
unset | Device or partition to use for root disk I/O stats. |
KEY |
unset | Public SSH key to use for authentication. Provided in hub. |
PORT |
45876 | Port or address:port to listen on. |
Beszel supports OpenID Connect and many OAuth2 authentication providers (see list below).
Visit the "Auth providers" page to enable your provider. The redirect / callback URL should be <your-beszel-url>/api/oauth2-redirect
.
Supported provider list
- Apple
- Bitbucket
- Discord
- Gitea
- Gitee
- GitHub
- GitLab
- Kakao
- LiveChat
- mailcow
- Microsoft
- OpenID Connect
- Patreon (v2)
- Spotify
- Strava
- Twitch
- VK
- Yandex
Note
This feature is new and has been tested on a limited number of systems. Please report any issues.
You can configure the agent to monitor the usage and I/O of more than one disk or partition. The approach differs depending on the deployment method.
Use lsblk
to find the names and mount points of your partitions. If you have trouble, check the agent logs.
Mount a folder from the partition's filesystem in the container's /extra-filesystems
directory, like the example below. The charts will use the name of the device or partition, not the name of the folder.
volumes:
- /mnt/disk1/.beszel:/extra-filesystems/disk1:ro
- /dev/mmcblk0/.beszel:/extra-filesystems/sd-card:ro
Set the EXTRA_FILESYSTEMS
environment variable to a comma-separated list of devices or partitions to monitor. For example:
EXTRA_FILESYSTEMS="sdb,sdc1,mmcblk0"
Because Beszel is built on PocketBase, you can use the PocketBase web APIs and client-side SDKs to read or update data from outside Beszel itself.
The hub and agent communicate over SSH, so they don't need to be exposed to the internet. Even if you place an external auth gateway, such as Authelia, in front of the hub, it won't disrupt or break the connection between the hub and agent.
When the hub is started for the first time, it generates an ED25519 key pair.
The agent's SSH server is configured to accept connections using this key only. It does not provide a pseudo-terminal or accept input, so it's impossible to execute commands on the agent even if your private key is compromised.
Admins have access to additional links in the hub, such as backups, SMTP settings, etc. The first user created is automatically an admin and can log into PocketBase.
Changing a user's role does not create a PocketBase admin account for them. To do that, go to Settings > Admins in PocketBase and add them manually.
Users can create their own systems and alerts. Links to PocketBase settings are not shown in the hub.
Read-only users cannot create systems but can view any system shared with them by an admin and create alerts.
Assuming the agent is running, the connection is probably being blocked by a firewall. You have two options:
- Add an inbound rule to the agent system's firewall(s) to allow TCP connections to the port. Check any active firewalls, like iptables, and your cloud provider's firewall settings if applicable.
- Alternatively, use software like Cloudflare Tunnel, WireGuard, or Tailscale to securely bypass your firewall.
You can test connectivity by running telnet <agent-ip> <port>
.
If using host network mode for the agent but not the hub, add your system using the hostname host.docker.internal
, which resolves to the internal IP address used by the host. See the example docker-compose.yml.
If using host network mode for both, you can use localhost
as the hostname.
Otherwise, use the agent's container_name
as the hostname if both are in the same Docker network.
Specify the filesystem/device/partition for disk I/O stats using the FILESYSTEM
environment variable.
If not set, the agent will try to find the partition mounted on /
and use that. This may not work correctly in a container, so it's recommended to set this value. Use one of the following methods to find the correct filesystem:
- Run
lsblk
and choose an option under "NAME." - Run
df -h
and choose an option under "Filesystem." - Run
sudo fdisk -l
and choose an option under "Device."
If container charts show empty data or don't appear at all, you may need to enable cgroup memory accounting. To verify, run docker stats
. If that shows zero memory usage, follow this guide to fix the issue:
https://akashrajpurohit.com/blog/resolving-missing-memory-stats-in-docker-stats-on-raspberry-pi/
Try upgrading your Docker version on the agent system. This issue was observed on a machine running version 24 and was resolved by upgrading to version 27.
Records for longer time periods are created by averaging stats from shorter periods. The agent must run uninterrupted for a full set of data to populate these records.
Pausing/unpausing the agent for longer than one minute will result in incomplete data, resetting the timing for the current interval.
Both the hub and agent are written in Go, so you can easily build them yourself, or cross-compile for different platforms. Please install Go first if you haven't already.
cd beszel && go mod tidy
Go to beszel/cmd/agent
and run the following command to create a binary in the current directory:
CGO_ENABLED=0 go build -ldflags "-w -s" .
The hub embeds the web UI in the binary, so you must build the website first. I use Bun, but you may use Node.js if you prefer:
cd beszel/site
bun install
bun run build
Then in beszel/cmd/hub
:
CGO_ENABLED=0 go build -ldflags "-w -s" .
You can cross-compile for different platforms using the GOOS
and GOARCH
environment variables.
For example, to build for FreeBSD ARM64:
GOOS=freebsd GOARCH=arm64 CGO_ENABLED=0 go build -ldflags "-w -s" .
You can see a list of valid options by running go tool dist list
.
Beszel is licensed under the MIT License. See the LICENSE file for more details.
Footnotes
-
Beszel only needs access to read container information. For linuxserver/docker-socket-proxy you would set
CONTAINERS=1
. ↩