Full-featured server monitors like Prometheus or Netdata are powerful, but they are heavy and need configuring. Sometimes you just want to glance at the CPU, RAM, disk and containers of your whole fleet without standing up a whole stack.

That is what Beszel is for: a lightweight server monitoring platform built on PocketBase that splits into two pieces, a hub with a web dashboard and an agent you install on each system. In this guide you bring both up with Docker Compose, pair them with a key, add your systems to the dashboard and set up alerts. The same explanation is available in Spanish.

Key takeaways

  • Beszel is a lightweight, MIT-licensed server monitor with around 23,500 GitHub stars; its latest version is v0.18.7, released on 5 April 2026.
  • It has two components: the hub (the web dashboard, built on PocketBase) listening on port 8090, and the agent, a Go binary that runs on each watched machine and listens on port 45876.
  • The agent reports host CPU, memory, disk, network, temperature and GPU, plus the stats of every Docker or Podman container.
  • Pairing relies on an ED25519 key the hub generates on its first start, plus a registration token per system; the agent can connect over WebSocket (agent-initiated) or SSH (hub-initiated).
  • It is far lighter than Netdata or a Prometheus-and-Grafana stack: the agent is a single binary that uses only a few tens of MB of RAM.

What is Beszel and why is it so lightweight?

Beszel is a server monitor aimed at homelabs and small fleets of machines. Its official repository describes it as "a lightweight server monitoring platform with Docker statistics, historical data, and alerts." The key word is lightweight. A solution like Prometheus plus Grafana means one container per piece, configuration files and its own query language; Beszel boils down to two binaries and a dashboard that works the moment it starts.

The secret to its lightness is the architecture. The hub is built on PocketBase, a Go backend that bundles database, API and authentication into a single executable, so you need no external database. The agent is likewise a dependency-free Go binary that collects the system’s metrics and sends them to the hub. There is no intermediate collector or time-series store to administer.

That is why the agent uses barely any resources and you can install it on modest machines, even a Raspberry Pi, without noticing it. If you are coming from trying fuller monitors like Glances, Beszel is the opposite end: fewer metrics per second, but a centralized view of your whole fleet at once and almost zero maintenance.

How does the hub-and-agent architecture work?

This is the part worth getting clear before you touch the docker-compose.yml, because Beszel is not a single application but two that talk to each other.

The hub is the brain and the visible face. It is the web application where you log in, see the dashboards, review history and define alerts. It stores all its data in its volume (beszel_data) and needs nothing else to start. Install the hub once, on the server you want to use as your monitoring centre.

The agent is the sensor. You install it on every machine you want to watch, including the hub’s own machine if you want to monitor that too. It reads the host’s metrics and, by mounting the Docker socket read-only, each container’s as well. By default it listens on port 45876.

The pairing between the two is the most carefully designed part. On its first start, the hub generates an ED25519 key. Each time you add a system in the dashboard, the hub gives you that public key and a unique token for that system. There are two ways to connect:

  • Over WebSocket: the agent initiates the connection to the hub URL and includes the token in the header; the hub verifies the token and signs a challenge with its private key to prove its identity. It is ideal when the agent sits behind a NAT or firewall, because it exposes no inbound port.
  • Over SSH: the hub initiates the connection to the agent’s SSH server on port 45876, authenticating with its public key. The agent’s SSH server offers no pseudo-terminal and accepts no input, so it is impossible to run commands on it even if the key leaks.

What do the hub and agent docker-compose.yml files look like?

We will bring up the hub first and then the agent. Both are independent services: the hub lives on one server and the agent on each watched machine, though you can run them on the same host without trouble.

The hub

Create a folder for the hub project and save this docker-compose.yml inside it. It publishes port 8090 and persists its data in a named volume. It pins version 0.18.7 instead of :latest, because a floating tag can change version during a simple restart and throw off the dashboard:

services:
  beszel:
    image: henrygd/beszel:0.18.7
    container_name: beszel
    restart: unless-stopped
    ports:
      - "8090:8090"
    volumes:
      - beszel_data:/beszel_data
    healthcheck:
      test: ["CMD", "/beszel", "health", "--url", "http://localhost:8090"]
      interval: 120s
      timeout: 10s
      retries: 3

volumes:
  beszel_data:

Start it and check that it responds:

docker compose up -d
docker compose ps

Open http://SERVER-IP:8090 in the browser. The first screen asks you to create the admin account; that account owns the dashboard, so use a strong password. If you are going to expose the hub outside your local network, do not publish port 8090 directly. Put it behind a reverse proxy with HTTPS, as explained in the guide on how to install Docker on Ubuntu 24.04 and the proxy articles in this same series.

The agent

On each machine you want to monitor, create another folder and save this docker-compose.yml. The agent uses network_mode: host to read the host’s network metrics correctly, mounts the Docker socket read-only to see the containers, and receives the public key and token the hub gives you:

services:
  beszel-agent:
    image: henrygd/beszel-agent:0.18.7
    container_name: beszel-agent
    restart: unless-stopped
    network_mode: host
    volumes:
      - beszel_agent_data:/var/lib/beszel-agent
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      LISTEN: 45876
      HUB_URL: "http://HUB-IP:8090"
      TOKEN: "PASTE-THE-TOKEN-HERE"
      KEY: "PASTE-THE-PUBLIC-KEY-HERE"

volumes:
  beszel_agent_data:

Fill HUB_URL with your hub’s address, and TOKEN and KEY with the values you copied from the dashboard when adding the system (you will see this in the next section). Then start the agent:

docker compose up -d
docker compose logs -f beszel-agent

In the logs you should see the agent connect to the hub. If the hub and the agent share the same machine, Beszel can communicate over a shared Unix socket instead of the network. To get started, the network connection you see here is more than enough.

How do you add systems and configure alerts?

With the hub running, open its dashboard and click the Add system button. It asks for a name, the host address and the agent’s port (45876 by default). On confirming, the hub shows you the token and public key you must paste into the agent’s docker-compose.yml; that is the step that closes the pairing. As soon as the agent starts with those values, the system goes active in the dashboard and you start seeing its CPU, memory, disk, network and container graphs within seconds.

To watch each new machine, you repeat the process: add a system in the hub and deploy its agent. As your estate grows, Beszel supports a universal token that lets you register agents without pre-registering each one, handy for provisioning machines automatically.

Alerts are configured per system or globally. You can set thresholds for CPU, memory, disk and temperature, and also be warned if an agent stops responding, which doubles as a check that the machine is still alive.

Beszel sends notifications by email or through messaging services via Shoutrrr, so you can route them to your own push-notification server. With ntfy you get the alerts on your phone without relying on third parties. It is a self-hosted, open-source push-notification service that delivers alerts to your phone or desktop via an app or browser.

When should you choose Beszel over heavier monitors?

Beszel does not compete on depth with Prometheus plus Grafana or with Netdata, and it does not try to. Its ground is different: giving a centralized, clear, low-maintenance view of a handful of servers. Choose Beszel when you want a single dashboard for your whole fleet, with history and alerts, without spending time configuring collectors, dashboards or queries.

Stick with a heavier tool when you need per-second metrics and fine diagnostics of a single server, where Netdata shines. The same goes for building custom dashboards and alerts over hundreds of series, which is exactly what the Prometheus and Grafana stack offers. Both fit together in a homelab: Beszel as the general traffic light for the whole fleet, and a detailed monitor on the critical machines. Beszel’s advantage is that its entry cost is so low it is almost always worth having, even if you already run another system.

Frequently asked questions

Do I need to install an agent on every server?

Yes: the hub only draws the data; the agent is what collects it. You install one on every machine you want to watch, including the hub’s own machine if you want its metrics too. The good news is that the agent is a tiny container: it deploys in seconds with the docker-compose.yml from this guide and uses very few resources. Putting it on ten servers adds hardly any load.

Is it safe to expose the hub to the Internet?

The hub has its own authentication and supports OAuth or OIDC, but you should not publish port 8090 raw. Always put it behind a reverse proxy with HTTPS or reach it over a VPN. The channel between hub and agent is already secure by design: it is authenticated with the ED25519 key. In SSH mode the agent does not even allow running commands, so a leaked key gives no access to the machine.

Can I monitor Docker containers with Beszel?

Yes, that is one of its main strengths. By mounting the Docker socket in the agent (/var/run/docker.sock read-only), Beszel automatically detects the running containers and shows each one’s CPU, memory and network usage. It also works with Podman. There is nothing extra to configure: as soon as the agent starts with the socket mounted, the containers appear in the dashboard.

Conclusion

Beszel is the fastest way to get a centralized view of your whole fleet without standing up a full monitoring stack. With two docker-compose.yml files, one for the hub and one for each agent, and a key-based pairing, you have it running in a few minutes. The dashboard gathers the CPU, memory, disk, network and containers of your whole fleet, with history and alerts.

The natural next step is to route those alerts to ntfy so you get them on your phone. Reserve a more detailed monitor like Netdata for the machines where you truly need per-second detail.

Sources

  1. Beszel official documentation: getting started
  2. Beszel: security and connection model
  3. Beszel official repository on GitHub
  4. What is Beszel (official documentation)
  5. henrygd/beszel image on Docker Hub

Route: Monitoring and observability with Docker