Beszel:5分钟搭建轻量服务器监控,告别 Prometheus 的配置地狱

前言:为什么我又折腾了一个监控工具

服务器监控这件事,属于那种「平时想不起来,出事就晚了」的存在。

我自己的情况是:VPS 从 3 台变成 8 台,后来又多了台 NUC 做 HomeLab(之前用来当黑苹果的小主机)。某天一台跑着定时任务的虚拟机 OOM 了三天才被发现 —— 因为压根没装监控。于是开始认真搞监控。

谷歌了一圈,展示的一大部份是 Prometheus + Grafana。但实地搞了一遍之后,痛点太真实了(真不是嫌麻烦):

  • 组件太多:Prometheus、Grafana、node_exporter、cAdvisor…… 光配置文件就能写一晚上
  • 吃资源:Prometheus 单进程 200-400MB,Grafana 又是 100-200MB,跑在 1C1G 的轻量云服务器上非常吃力
  • 学习曲线陡峭:PromQL 是好东西,但为了看个 CPU 利用率还得写 rate(node_cpu_seconds_total[5m]),属实劝退

当然不是说 Prometheus 不好 —— 它是工业级方案,适合 100+ 节点的大规模集群。但对我来说,需求其实很简单:知道每台机器还活着,CPU/内存/磁盘有没有异常,Docker 容器有没有挂掉

于是找到了 Beszel(GitHub 真实个好地方😘)。

这东西在 GitHub 上有 22k stars,MIT 协议开源,Go 语言写的,v0.18.7,142 位贡献者。最吸引我的是它的哲学:两个组件,五分钟上线,每台被监控机器只吃不到 10MB 内存。Reddit 上有人评价它是 “the most elegant self-hosted monitoring tool I’ve used”(“我用过的最优雅的自托管监控工具”)—— 用了之后我信了。

这篇文章不是官方文档的翻译,而是我从零部署到稳定运行一个月后的实战总结。

Beszel 是什么,能做什么

架构:简单到只有两个组件

Beszel 采用经典的 Hub-Agent 架构:

graph LR
    A[被监控主机1] -->|Agent| B[Hub]
    C[被监控主机2] -->|Agent| B
    D[被监控主机3] -->|Agent| B
    B --> E[Web UI 面板]
  • Hub(中心):基于 PocketBase 的 Web 应用,提供仪表板、用户管理、告警配置。默认端口 8090
  • Agent(代理):运行在每台被监控主机上,采集指标后发给 Hub。默认端口 45876

两个组件,没有 Redis、没有时序数据库、没有额外的 exporter。这对比 Prometheus 生态让人感动到想哭。

能监控什么

指标类别具体内容
CPU主机 + 每个 Docker / Podman 容器
内存主机 + 容器(含 swap、ZFS ARC)
磁盘使用率 + I / O,支持多分区
网络主机 + 容器带宽
Docker 容器每个容器的 CPU / 内存 / 网络历史
GPUNvidia / AMD / Intel(实验性 NVML 支持)
温度主机传感器(CPU、NVMe 等)
电池主机电池电量(笔记本/ UPS)
系统负载Load Average
S.M.A.R.T.磁盘健康状态(含 eMMC 磨损)

基本覆盖了个人开发者和中小团队 90% 的监控需求。

跟其他方案比呢?

维度Prometheus + GrafanaNetdataBeszel
组件数4+12
内存占用500MB+200-500MB<128MB(Hub)+ <10MB(Agent)
部署时间2-8 小时10 分钟5 分钟
Docker 监控需要 cAdvisor内置内置
自定义指标无限制(PromQL)丰富固定指标集
仪表板自定义完全自由高度可定制固定布局
适用规模100+ 节点中等规模10-100 节点
协议Apache 2.0GPL v3MIT

适用与不适用场景

适合

  • 个人开发者 / 小团队的 10-100 台服务器
  • HomeLab 玩家
  • Docker / Podman 环境下的容器监控
  • 资源敏感环境(1C1G VPS 也能跑)
  • 追求快速搭建、零学习成本的场景

不适合

  • 100+ 节点的大规模集群
  • 需要自定义指标和复杂查询的场景
  • 企业级权限管理和审计需求
  • 需要与现有 Prometheus 生态深度集成的场景

快速上手:5 分钟跑起来

先说最快的方式 ——Docker Compose 一键启动。

第一步:部署 Hub

Terminal window
mkdir -p ~/beszel/hub && cd ~/beszel/hub
cat > docker-compose.yml << 'EOF'
services:
beszel:
image: henrygd/beszel:latest
container_name: beszel
restart: unless-stopped
environment:
APP_URL: http://localhost:8090 # 改成你的实际访问地址
ports:
- "8090:8090"
volumes:
- ./beszel_data:/beszel_data
EOF
2 collapsed lines
docker compose up -d

30 秒后,访问 http://你的IP:8090,看到注册页面就是成功了。

第二步:创建管理员,添加 Agent

  1. 访问 Web UI,用邮箱 + 密码创建管理员账户
  2. 点击 “Add System”,选择 Docker 安装方式
  3. 复制生成的 docker-compose.yml(里面已经包含了 KEYTOKEN

第三步:在被监控主机上启动 Agent

Terminal window
mkdir -p ~/beszel/agent && cd ~/beszel/agent
# 粘贴上一步从 Web UI 复制的 docker-compose.yml
# 内容大概长这样:
cat > docker-compose.yml << 'EOF'
services:
beszel-agent:
image: henrygd/beszel-agent:latest
container_name: beszel-agent
restart: unless-stopped
network_mode: host
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
LISTEN: 45876
6 collapsed lines
KEY: "ssh-ed25519 AAAA..."
HUB_URL: "http://你的HubIP:8090"
TOKEN: "token_value"
EOF
docker compose up -d

回到 Web UI,Dashboard 上应该出现一个绿色圆点 —— 恭喜,监控已上线。

部署方案细选

上面的 Docker Compose 是最快的方式,但不同场景有不同选择:

场景推荐方案理由
快速体验 / 测试Docker Compose5 分钟上线
生产环境Docker Compose(Hub 和 Agent 分离)易维护、易升级
无 Docker 环境二进制 + systemd零依赖、最小资源
资源极度受限二进制安装32MB 内存就能跑 Agent

二进制安装

Terminal window
# Hub
curl -sL https://get.beszel.dev/hub -o /tmp/install-hub.sh
chmod +x /tmp/install-hub.sh
sudo /tmp/install-hub.sh -p 8090 -c "http://your-domain.com"
# Agent
curl -sL https://get.beszel.dev -o /tmp/install-agent.sh
chmod +x /tmp/install-agent.sh
sudo /tmp/install-agent.sh # 交互式输入 KEY / TOKEN / HUB_URL

systemd 管理 Hub(生产环境推荐)

Terminal window
sudo tee /etc/systemd/system/beszel.service << 'EOF'
[Unit]
Description=Beszel Hub
After=network.target
[Service]
Type=simple
Restart=always
RestartSec=3
WorkingDirectory=/opt/beszel
ExecStart=/opt/beszel/beszel serve --http "0.0.0.0:8090"
Environment="APP_URL=http://your-domain.com:8090"
[Install]
WantedBy=multi-user.target
4 collapsed lines
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now beszel.service

Agent 通信模式选择

Beszel 支持两种通信方式:

  • SSH 模式:Hub 主动连接 Agent。适合 Agent 在 NAT 后面、Hub 能访问 Agent 的场景。Agent 监听 45876 端口
  • WebSocket 模式:Agent 主动连接 Hub。适合 Agent 能访问 Hub 的场景。更简单,不需要 Agent 开端口

Docker Compose 部署默认走 WebSocket 模式 ——Agent 通过 HUB_URL 主动连 Hub,不需要开 45876 端口。如果你的网络拓扑是 Hub 有公网 IP、Agent 在内网,这就是最省事的方案。

关键配置与踩坑指南

必填环境变量速查

Hub 端

参数说明生产建议
APP_URLHub 访问地址必填,设错会导致链接和 OAuth 回调异常
DISABLE_PASSWORD_AUTH禁用密码登录启用 OAuth 后设为 true
MFA_OTP双因素认证生产环境建议开启
SHARE_ALL_SYSTEMS所有用户共享系统通常保持 false

Agent 端

参数说明
KEYSSH 公钥,从 Hub Web UI 获取
TOKEN注册令牌,从 Hub Web UI 获取
HUB_URLHub 的完整 URL(含协议和端口)
LISTENSSH 监听端口,默认 45876
NETWORKtcp / tcp4 / tcp6 / unix

磁盘监控配置

默认情况下 Agent 可能没有监控到你真正关心的磁盘分区:

Terminal window
# 先确认设备名
lsblk
df -h
# 在 Agent 环境变量中指定
EXTRA_FILESYSTEMS: "sdb,sdc,nvme0n1"

网络接口过滤

如果你的机器上有 Docker 虚拟网桥(docker0br-xxx),带宽统计会包含这些内部流量。建议做过滤:

Terminal window
# 白名单模式:只监控物理网卡
NICS: "eth0,eth1"
# 黑名单模式:排除虚拟接口
NICS: "-docker*,lo,veth*"

温度传感器配置

Terminal window
# 指定面板上显示的主传感器
PRIMARY_SENSOR: "coretemp"
# 白名单:只显示 CPU 温度
SENSORS: "coretemp*"
# 黑名单:排除某些传感器
SENSORS: "-k10temp*"

反向代理 + HTTPS

如果你有域名,强烈建议用 Nginx 反代,套上 HTTPS。

server {
listen 443 ssl http2;
server_name monitor.your-domain.com;
ssl_certificate /etc/ssl/certs/monitor.pem;
ssl_certificate_key /etc/ssl/private/monitor.key;
location / {
proxy_pass http://127.0.0.1:8090;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket 支持:这四行是关键
5 collapsed lines
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

OAuth 登录

Beszel 支持 GitHub、Google、GitLab 等 OAuth2 提供商。 配置路径:Settings → Authentication。

建议流程:

  1. 先保留密码登录,配置好 OAuth
  2. 用新标签页测试 OAuth 登录,确认正常工作
  3. 再设置 DISABLE_PASSWORD_AUTH: "true" 关闭密码登录

敏感信息安全管理

Terminal window
# 方案一:FILE 环境变量(推荐)
echo "ssh-ed25519 AAAA..." > /etc/beszel/key.pem
chmod 600 /etc/beszel/key.pem
# docker-compose.yml 中引用
environment:
KEY_FILE: /etc/beszel/key.pem
TOKEN_FILE: /etc/beszel/token.txt
volumes:
- /etc/beszel/key.pem:/etc/beszel/key.pem:ro
- /etc/beszel/token.txt:/etc/beszel/token.txt:ro
Terminal window
# 方案二:Docker Secrets(Swarm 环境)
docker secret create beszel_key ./key.pem
docker secret create beszel_token ./token.txt

告警与运维:监控的监控

告警配置策略

Beszel 内置了告警功能,支持以下指标的阈值配置:

  • CPU 使用率
  • 内存使用率
  • 磁盘使用率
  • 网络带宽
  • 温度
  • 系统负载
  • 系统状态(在线 / 离线)

配置告警时建议遵循分级策略:

级别描述示例
P0 紧急服务不可用、数据丢失系统离线、磁盘 95%+
P1 重要指标异常,需尽快处理内存 90%+、CPU 持续 95%+
P2 警告资源预警、性能下降磁盘 80%+、负载持续偏高

日常健康检查

把下面这个脚本加到 cron 里,每天跑一次。不熟悉 cron 的话先搜「Linux crontab 教程」了解一下:

#!/bin/bash
# 每日 Beszel 健康检查
set -e
echo "=== Beszel 健康检查 $(date) ==="
# 1. Hub 状态
if curl -sf http://localhost:8090/api/health > /dev/null; then
echo "✓ Hub 正常"
else
echo "✗ Hub 异常!"
fi
# 2. 数据目录大小
echo "数据目录占用:"
5 collapsed lines
du -sh ~/beszel/hub/beszel_data
# 3. 最近错误日志
echo "最近错误(如有):"
docker compose -f ~/beszel/hub/docker-compose.yml logs --tail 100 2>&1 | grep -i error | tail -5 || echo " 无错误"

数据备份

Beszel 使用 SQLite 存储数据,备份只需拷贝数据目录:

Terminal window
# 手动备份
tar -czf beszel_backup_$(date +%Y%m%d).tar.gz \
~/beszel/hub/beszel_data \
~/beszel/hub/docker-compose.yml
# crontab 自动备份(每天凌晨 2 点,保留 7 天)
0 2 * * * tar -czf /backup/beszel_$(date +\%Y\%m\%d).tar.gz /opt/beszel/beszel_data
0 3 * * * find /backup -name "beszel_*.tar.gz" -mtime +7 -delete

Beszel v0.18 也支持自动备份到 S3 兼容存储,可以在 Web UI 中配置。

升级流程

Terminal window
cd ~/beszel/hub
# 1. 备份
cp docker-compose.yml docker-compose.yml.bak
tar -czf beszel_data_backup.tar.gz beszel_data/
# 2. 拉取新镜像并重建
docker compose pull
docker compose up -d
# 3. 验证
curl -sf http://localhost:8090/api/health
docker compose logs --tail 20
# 4. 清理旧镜像
1 collapsed line
docker image prune -f

回滚

Terminal window
# 1. 停服
docker compose down
# 2. 恢复 compose 文件
cp docker-compose.yml.bak docker-compose.yml
# 3. 或直接指定旧版本
# 编辑 compose 文件:image: henrygd/beszel:0.17.3
# 4. 重启
docker compose up -d
# 5. 如果数据也出了问题
rm -rf beszel_data
tar -xzf beszel_data_backup.tar.gz
1 collapsed line
docker compose up -d

常见问题 FAQ

Q: Agent 连不上 Hub 怎么排查?

按顺序检查:

  1. 网络:从 Agent 主机 curl http://HubIP:8090/api/health 能通吗?
  2. 防火墙:8090 端口是否开放?
  3. 配置:KEYTOKENHUB_URL 三个变量是否全部正确?(HUB_URL 要带协议)
  4. 时间同步:Agent 和 Hub 的系统时间差太大会导致认证失败,跑一下 ntpdate pool.ntp.org

Q: 系统显示绿色但数据不更新?

  • Agent 进程还活着吗?docker ps | grep beszel-agent
  • 磁盘满了?df -h 看 Agent 的数据目录
  • Docker 套接字权限对了吗?ls -la /var/run/docker.sock
  • 试着重启 Agent:docker restart beszel-agent

Q: 反向代理后图表空白 / 不刷新?

九成是 WebSocket 没代理对。确认 nginx 配置里这四行:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

还要确认没有对 text/event-stream 开启 gzip 压缩。浏览器 F12 → Network 看 WS 连接状态。

Q: SQLite 撑得住吗?需要换数据库吗?

对于 Beszel 的使用场景(10-100 台机器),SQLite 完全够用。PocketBase 对 SQLite 做了大量优化(WAL 模式、合理索引)。如果实在担心,做好定期备份即可。目前 Beszel 不支持更换数据库后端,也不需要。

Q: 能监控非 Docker 的进程吗?

Beszel 监控的是主机级别指标(CPU、内存、磁盘等),不区分 Docker 还是宿主机进程。Docker 容器的独立统计是额外功能。你也可以通过 EXCLUDE_CONTAINERS 排除某些容器、通过 EXTRA_FILESYSTEMS 添加额外磁盘监控。

Q: 监控中心自己宕机了怎么办?

这是个经典问题 —— 谁来监控监控系统本身?

  • 可以在另一台机器上部署第二个 Beszel 实例,专门监控第一个
  • 或者用更轻量的方式:uptime 监控(Uptime Kuma)+ 健康检查脚本
  • 至少设置一个「监控离线」告警,这样 Hub 宕机时你还能收到通知

总结:监控这件事,简单就是最大的优雅

用了一个月 Beszel 之后,我最大的感受是:它不会让你觉得「我在做监控」,而是让你觉得「我有监控」

不需要写 PromQL、不需要维护 Grafana 面板 JSON、不需要纠结 scrape interval 和 retention policy。打开面板,几台服务器的状态一目了然 —— 绿的放心,红的排查。告警配好之后,平时几乎不用管它,有问题它会主动通知你。

当然它不是银弹。如果需要自定义指标、跨数据源查询、复杂的聚合管道,Prometheus + Grafana 依然是正解。但对于独立开发者、小团队、HomeLab 玩家来说,Beszel 的「够用就好」哲学恰恰是它最大的价值。

GitHub:henrygd/beszel
文档:beszel.dev
协议:MIT