Skip to main content

Simple server monitoring with Beszel

When self-hosting services with Docker, it can be really useful to know not only if they are up or down, but also how many resources each container is using, and how this changes over time. This can inform choices about whether the server has the appropriate resources, or whether some scaling is required. Beszel caught my attention because it is both super lightweight, and easy to setup.

This guide was written based on Beszel v0.9.1

What is Beszel?

Beszel monitors resource use one or more servers. It consists of a “hub” which is where you can see metrics about the other servers, which are running “agents”. Both the hub and the agent can be installed through Docker. In addition to being super easy to setup, Beszel brings a couple of key features that are essential, even in a lightweight setup:

  1. Email notifications if the servers being monitored exceed a threshold (for CPU, memory etc).
  2. The ability to monitor individual docker containers on the monitored server.
  3. Login through OIDC is always nice!

The end product will look something like this (this screenshot is from the GitHub README, I would have put mine but I don’t have that many servers!)

a screenshot of the Beszel dashboard

Individual docker services are split up by colour on graphs for each metric. You can filter for an individual service to isolate usage from the rest. This screenshot is from one of my servers (still plenty of resources to spare!)

a screenshot of the individual graphs in the Beszel dashboard

Installing Beszel

The Hub

First, you need to pick a machine as your hub. This could be the same machine you wish to monitor (so the machine monitors itself), but then it wouldn’t be able to notify you if it crashes or otherwise gets locked up. You can use Beszel on pikapods for the hub as a cheap option if you don’t have another inexpensive server lying around. On the hub, the following service in a compose.yml file can be used.

services:
  beszel:
    image: henrygd/beszel:latest
    container_name: beszel
    restart: unless-stopped
    extra_hosts:
      - host.docker.internal:host-gateway
    ports:
      - "127.0.0.1:8090:8090"
    volumes:
      - ./beszel_data:/beszel_data

The web interface should be placed behind a reverse-proxy, whichever you prefer should work just fine. I use Caddy. The Caddyfile would look like something like this[1].

monitors.example.com {
	reverse_proxy 127.0.0.1:8090
}

To start, run the usual docker compose up -d.

The agent

Next, the agent needs to be installed on each server that is going to be monitored. You need to have the hub up and ready for configuration before this step. The hub will present the following UI on initial setup[2]

a screenshot of the popup that the hub will display on initial setup

Hitting the Copy docker compose button will copy the yaml syntax for you to the clipboard. It will look something like this. This is used on the agent server.

services:
  beszel-agent:
    image: "henrygd/beszel-agent"
    container_name: "beszel-agent"
    restart: unless-stopped
    network_mode: host
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      # monitor other disks / partitions by mounting a folder in /extra-filesystems
      # - /mnt/disk/.beszel:/extra-filesystems/sda1:ro
    environment:
      PORT: <some port>
      KEY: <some key>

The agent can now be started with docker compose up -d. Make sure that you have the port open so that the hub can connect to it. This doesn’t necessarily have to be open to the internet, you could use something like a tailnet, or configure the firewall such that only the hub is allowed to connect on that port, or use a private network. The security considerations of the setup are outlined here.

Proceed by clicking Add symstem on the hub, and if everything is working, you should begin seeing metrics come through.

Setting up email notifications

Now that the hub and agent are connected, it is time to setup email notifications if the server exceeds a threshold.

Configure SMTP server

I would recommend using a service like mailgun to send the emails. After you have an SMTP service ready, go to /settings/notifications on the Beszel hub, and click configure and SMTP server. This will open up Pocketbase. You can login with the same credentials as the first admin user you setup in Beszel. Once in Pocketbase, click on settings then mail settings. Toggle Use SMTP mail server to the on position. Enter the details for the SMTP account you wish to use. You can send a test email to confirm that everything is working.

Enable notifications for servers

On the main dashboard, click the bell icon. This will open a popover where you can then select the thresholds that should trigger a notification.

Conclusion

More agents can be added through the same methodology. Now if anything goes wrong, you should get notified so that you can investigate.


  1. I run Caddy as a systemctl service, however it can also be done in the compose. Just make sure not to compose up and down with the caddy service in the compose, or you may run in to certificate rate limits. ↩︎

  2. The two values that I have redacted aren’t actually all that sensitive. ↩︎