> ## Content Index
> Fetch the complete content index at: https://blog.uptime.bet/llms.txt
> Use this file to discover other available public pages before exploring further.

# Beszel: Lightweight Server Monitoring for Your Homelab with Docker Compose
- URL: https://blog.uptime.bet/beszel-lightweight-server-monitoring-docker/
- Published: 2026-11-02T12:22:38.000Z
- Updated: 2026-11-02T12:22:38.000Z
- Description: Beszel is an MIT-licensed hub-and-agent monitoring tool that shows CPU, RAM, disks, Docker containers, S.M.A.R.T. and more for all your servers. Here is how to run version 0.21 with Docker Compose.
- Author: Alexandre Nebeling
- Tags: Self-Hosted, Monitoring, Docker, Homelab, Open Source

Once your homelab grows past one box, a simple question becomes surprisingly hard to answer: *how are my servers actually doing?* Is the NAS running hot? Which container is eating all the RAM? Is that old SSD about to die? You can build a Prometheus + Grafana stack for this, but for most homelabs that is a lot of moving parts. **Beszel** takes the opposite approach: one small hub, one tiny agent per machine, and a clean dashboard that works out of the box.

In this guide we look at what Beszel does, what is new in the current **v0.21** release line, and how to run it with Docker Compose.

## What is Beszel?

Beszel describes itself as a *lightweight server monitoring platform that includes Docker statistics, historical data, and alert functions*. It is written in Go, released under the **MIT license** and has passed 26,000 stars on GitHub. The latest release at the time of writing is **v0.21.1** (22 October 2026).

![Beszel dashboard table with several systems and their resource usage](https://blog.uptime.bet/content/images/2026/11/beszel-dashboard.png)

The Beszel dashboard gives you one row per system with live CPU, memory, disk and network usage. [Source: beszel.dev](https://beszel.dev/guide/what-is-beszel?ref=blog.uptime.bet) (MIT)

## Hub and agent: how Beszel works

Beszel has exactly two components:

- **The hub** is the web application. It is built on [PocketBase](https://pocketbase.io/?ref=blog.uptime.bet), stores the history, sends alerts and serves the dashboard.
- **The agent** runs on every system you want to monitor. It collects metrics and hands them to the hub.

Agents can connect *to* the hub over a WebSocket (using `HUB_URL` and a token), or the hub can connect to the agent over SSH on the agent's listen port (45876 by default). Each agent is tied to the hub's public key, so a random client cannot simply pull your stats. The agent is available as a Docker image, a single binary with a Linux install script, Homebrew, WinGet/Scoop and even a Home Assistant add-on.

## What Beszel monitors

The list of supported metrics has grown a lot over the last releases:

- **CPU, memory, disk usage and disk I/O** for the host, including swap and ZFS ARC
- **Docker and Podman containers**: CPU, memory and network history per container, plus container status
- **Network usage**, load average, temperatures and (on Linux) fan speeds
- **GPU usage and power draw** for NVIDIA, AMD and Intel
- **S.M.A.R.T. disk health**, including eMMC wear and Linux mdraid array health
- **ZFS pools and datasets**: capacity, health, I/O and scrub status
- **Network monitors** (ICMP, TCP, HTTP and DNS) probed directly from the agents
- **Battery charge** for laptops and some peripherals

![Beszel system detail page with charts for CPU, memory, disk, network, temperature and Docker containers](https://blog.uptime.bet/content/images/2026/11/beszel-system-full.png)

The system page shows the history for a single machine, from CPU and memory to disk I/O, temperatures and per-container usage. [Source: beszel.dev](https://beszel.dev/guide/what-is-beszel?ref=blog.uptime.bet) (MIT)

On top of that you get **multi-user support** (users manage their own systems, admins can share systems), **OAuth/OIDC login** with the option to disable password login, and **automatic backups** to disk or S3-compatible storage.

## What's new in v0.19 to v0.21

Beszel ships fast. The releases since September 2026 added a lot of homelab-friendly features:

- **v0.19.0** (September): ZFS pool and dataset monitoring, container health alerts with log excerpts, alerts for failed systemd services and for CPU I/O wait. Important: agents now **verify HTTPS certificates**. If your hub uses a self-signed certificate, set `CA_CERT_FILE` on the agent or the connection will be rejected.
- **v0.20.0** (September): network monitoring from agents, an "image update available" flag for containers and btrfs reporting.
- **v0.21.0** (October): a list of pending package updates on the system page, Wi-Fi signal strength, TLS certificate expiry checks for HTTPS monitors, systemd service logs and a `DISABLE_SSH` option for the hub.
- **v0.21.1** (October): mainly API changes. Memory values are now also reported as raw bytes, and the old GB fields are deprecated. Only relevant if you build integrations on the API.

## Installing Beszel with Docker Compose

The official docs provide a Compose file that runs the hub **and** a local agent on the same machine. The two talk over a shared unix socket, which avoids network headaches between containers.

### 1\. Create a folder and the Compose file

```bash
mkdir -p /opt/beszel && cd /opt/beszel
nano docker-compose.yml

```

```yaml
services:
  beszel:
    image: henrygd/beszel:0.21.1
    container_name: beszel
    restart: unless-stopped
    environment:
      APP_URL: https://beszel.example.com
    ports:
      - 8090:8090
    volumes:
      - ./beszel_data:/beszel_data
      - ./beszel_socket:/beszel_socket

  beszel-agent:
    image: henrygd/beszel-agent:0.21.1
    container_name: beszel-agent
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./beszel_agent_data:/var/lib/beszel-agent
      - ./beszel_socket:/beszel_socket
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      LISTEN: /beszel_socket/beszel.sock
      HUB_URL: http://localhost:8090
      TOKEN: <token>
      KEY: "<key>"

```

The upstream example uses the `latest` tag. Pinning a version, as above, makes updates a deliberate step. Set `APP_URL` to the address you will use for the hub, because Beszel uses it for notification links and for the agent config it generates.

### 2\. Start the hub and create your account

```bash
docker compose up -d beszel

```

Open port 8090 (or your domain) and create the first user. That account becomes the admin.

### 3\. Add the local system

Click **Add System**. Use the socket path `/beszel_socket/beszel.sock` as Host/IP, copy the shown **public key** and **token** into the `KEY` and `TOKEN` variables of the agent, then start everything:

```bash
docker compose up -d

```

After a few seconds the new system should turn green in the table.

### Why does the agent use host networking?

The agent runs with `network_mode: host` so it can read the host's real network interface statistics. If you do not care about host network stats, you can drop that line and map the port instead. Also note that rootless Docker or Podman cannot see most host-level data, so temperatures, GPU, S.M.A.R.T. and systemd monitoring may be missing in that setup.

## Adding more servers

For every additional machine, click **Add System** in the hub and copy the ready-made `docker-compose.yml` or the binary install command from the dialog. A minimal remote agent looks like this:

```yaml
services:
  beszel-agent:
    image: henrygd/beszel-agent:0.21.1
    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
      # extra disks: mount a folder into /extra-filesystems
      # - /mnt/disk1/.beszel:/extra-filesystems/disk1:ro
    environment:
      LISTEN: 45876
      KEY: "<public key>"
      HUB_URL: "https://beszel.example.com"
      TOKEN: "<token>"

```

If you have many machines, create a **universal token** under `/settings/tokens`. Agents started with that token register themselves with the hub, so you do not have to add each system by hand first.

## Running the hub behind Traefik

If you already use Traefik (like in our [Homepage dashboard guide](https://blog.uptime.bet/homepage-dashboard-homelab-docker/)), replace the `ports:` section of the hub with labels. The docs point out that the proxy must pass **WebSocket** connections, otherwise agents using a universal token cannot connect.

```yaml
  beszel:
    image: henrygd/beszel:0.21.1
    container_name: beszel
    restart: unless-stopped
    environment:
      APP_URL: https://beszel.example.com
    volumes:
      - ./beszel_data:/beszel_data
      - ./beszel_socket:/beszel_socket
    networks:
      - traefik
    labels:
      - traefik.enable=true
      - traefik.http.routers.beszel.rule=Host(`beszel.example.com`)
      - traefik.http.routers.beszel.entrypoints=websecure
      - traefik.http.routers.beszel.tls.certresolver=letsencrypt
      - traefik.http.services.beszel.loadbalancer.server.port=8090

```

Traefik handles WebSockets without extra configuration. With Nginx you need the usual `Upgrade` and `Connection` headers and a longer `proxy_read_timeout`; the docs have full Caddy and Nginx examples.

## Alerts: plug in ntfy or Gotify

Alerts are configured per system in the table, and the notification targets live under **Settings > Notifications**. Beszel uses [Shoutrrr](https://github.com/nicholas-fedor/shoutrrr?ref=blog.uptime.bet) URLs, so you can send alerts to Discord, Telegram, Slack, Matrix, email and many more. If you followed our guides on [ntfy](https://blog.uptime.bet/ntfy-self-hosted-push-notifications-docker/) or [Gotify](https://blog.uptime.bet/gotify-self-hosted-push-notifications-docker/), you are one line away from push alerts on your phone:

```text
ntfy://:accesstoken@ntfy.example.com/homelab-alerts
gotify://gotify.example.com/AppToken

```

![Beszel notification settings page with webhook and push URLs](https://blog.uptime.bet/content/images/2026/11/beszel-settings-notifications.png)

Notification settings in Beszel: add one or more Shoutrrr URLs and send a test notification. [Source: beszel.dev](https://beszel.dev/guide/what-is-beszel?ref=blog.uptime.bet) (MIT)

Useful alerts to start with: system down, disk usage above 85 %, high temperature and the S.M.A.R.T. failure alert.

## Tips from practice

- **Back up `beszel_data`.** It contains the PocketBase database with users, systems and history. Beszel can also create backups to disk or S3 on its own.
- **Monitor extra disks** by mounting a folder from each disk into `/extra-filesystems` in the agent container.
- **Show it on your dashboard.** [Homepage](https://blog.uptime.bet/homepage-dashboard-homelab-docker/) has a Beszel widget (`type: beszel`, `version: 2`) with an overview of all systems or details for one.
- **Pair it with uptime checks.** Beszel tells you how a machine is doing; [Healthchecks](https://blog.uptime.bet/healthchecks-self-hosted-cron-job-monitoring-docker/) tells you when a cron job or backup silently stopped. Patch status is a different job again, which is where [PatchMon](https://blog.uptime.bet/patchmon-self-hosted-linux-patch-management-docker/) comes in, although Beszel 0.21 now lists pending package updates too.

## Beszel vs Uptime Kuma vs Netdata

|              | Beszel                                             | Uptime Kuma                                  | Netdata                         |
| ------------ | -------------------------------------------------- | -------------------------------------------- | ------------------------------- |
| Main job     | Resource monitoring of your servers and containers | Availability checks of services and websites | Very detailed real-time metrics |
| Needs agent  | Yes, tiny agent per host                           | No                                           | Yes, per host                   |
| History      | Yes                                                | Yes (uptime/response time)                   | Yes                             |
| Status pages | No                                                 | Yes                                          | No                              |
| Resource use | Very low                                           | Low                                          | Higher, very detailed           |
| License      | MIT                                                | MIT                                          | GPL-3.0 (agent)                 |

In short: Beszel and Uptime Kuma complement each other. Kuma checks *whether* a service answers; Beszel shows *why* a server is struggling. Netdata goes much deeper on metrics but is also heavier. If you want a simple "how are all my boxes doing" view, Beszel is hard to beat.

## Conclusion

Beszel hits a sweet spot for homelabs: it installs in minutes, uses almost no resources and still covers containers, disks, GPUs, ZFS and alerts. The rapid release pace means new features arrive every few weeks. Just keep an eye on the release notes before updating, as v0.19 showed with its stricter certificate checks.

## Sources

- [Beszel on GitHub](https://github.com/henrygd/beszel?ref=blog.uptime.bet) (MIT license)
- [Beszel releases](https://github.com/henrygd/beszel/releases?ref=blog.uptime.bet)
- [Beszel documentation: Getting Started, Agent Installation, Reverse Proxy, Notifications](https://beszel.dev/guide/getting-started?ref=blog.uptime.bet)
- [Homepage Beszel widget](https://gethomepage.dev/widgets/services/beszel/?ref=blog.uptime.bet)