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 several machines 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: where a solution like Prometheus plus Grafana means several containers, 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 many servers 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. You usually install it once, on the server you want to use as your monitoring hub.

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; typically the hub lives on one server and the agent on each watched machine, but 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 several machines, you repeat the process: add a new system for each one and deploy its agent. If you manage many servers, Beszel supports a universal token that lets you register agents without pre-registering each one, very 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; if you use ntfy, you will get the alerts on your phone without relying on third parties.

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 several machines, with history and alerts, without spending time configuring collectors, dashboards or queries.

Stick with a heavier tool when you need per-second metrics and very fine diagnostics of a single server, where Netdata shines, or when you want to build custom dashboards and alerts over hundreds of series, which is exactly what the Prometheus and Grafana stack offers. Many homelabs end up using both: 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 one that collects it is the agent, and you have to 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, so 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 and, 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 several servers 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, in a few minutes you have the CPU, memory, disk, network and containers of your whole fleet in a single dashboard, with history and alerts. The natural next step is to route those alerts to ntfy so you get them on your phone, and 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