结论先行:拥有 2 台以上 VPS 的独立开发者,多节点资源监控首选 Beszel。架构极简(Hub-Agent 模式),Hub 端用 Docker 一行启动(内存仅占 30MB,默认端口 8090),各节点 Agent 单二进制常驻(内存占用不到 10MB,通信端口 45876)。相比动辄消耗数百兆内存的 Prometheus + Grafana 全家桶轻量 90% 以上,又比只能探测存活的 Uptime Kuma 补齐了 CPU、内存、磁盘与 Docker 容器负载指标,配置 Telegram 机器人即可实现秒级故障与爆盘预警。

你的 VPS 数量从 1 台变成 3 台,手动逐台 SSH 敲 htop 查看负载已经力不从心。等到用户报错甚至磁盘被日志撑爆时再去排查,往往为时已晚。本篇为你梳理从零搭建 Beszel 集中化资源监控中心的完整操作。

全景图解导览:Beszel监控配置速查:轻量级多VPS资源监控与告警实战 STAGE 01 · 问题起爆 写在前面 • Prometheus+Grafana:功 能全面,但每个组件常驻消… • Zabbix:重度依赖传统数据… 定位核心风险卡点 STAGE 02 · 机制拆解 期望目标 • 拆解核心协议与准则 • 识别关键决策分水岭 • 识别关键决策分水岭 理清底层因果逻辑 STAGE 03 · 方案对照 技术架构与横向对比 • Hub-Agent架构模型:<svg width="100%"height="… • 常见监控方案量化对比:|… 对齐量化实测标尺 STAGE 04 · 工程落地 在主控VPS上部署Beszel… • 创建部署目录与生产级编排 文件:选择一台网络连通性… • 可复现的验收自检清单 锁死生产确定性

0、写在前面

很多出海独立开发者经历过这样的尴尬时刻:

  • 博客、API、数据库分散在不同区域的廉价 VPS 上;
  • 某个爬虫疯狂抓取导致 CPU 持续跑满,或者某项服务内存泄漏触发 OOM 崩溃,自己却毫不知情;
  • 磁盘被轮转失控的容器日志塞满,导致连 SSH 终端都无法分配 pty 登录。

传统的企业级监控方案对于独立开发者过于繁重:

  • Prometheus + Grafana:功能全面,但每个组件常驻消耗数百 MB 内存,配置报警规则(Alertmanager)陡峭复杂;
  • Zabbix:重度依赖传统数据库,运维负担过重;
  • Uptime Kuma:优秀的 HTTP 存活探针,但不提供服务器内部的 CPU、内存和磁盘 IO 统计。

Beszel 正好切中独立开发者的甜区:轻量、优雅、原生支持 Docker 容器指标聚合,几分钟即可交付全景监控。

问题现场解剖:写在前面 ⚠️ 从问题出发:表面症状是如何一步步演变为生产故障或降权的? 独立开发者工具箱 · CH-43 · 核心卡点传导链 1. Prometheus+Grafana 功能全面,但每个组件常驻消耗 数百MB内存,配置报警规则(… 症结:认知偏差与配置盲区 2. Zabbix 重度依赖传统数据库,运维负担 过重; 传导:隐性劣化与边界失守 3. Uptime Kuma 优秀的HTTP存活探针,但不提 供服务器内部的CPU、内存和磁… 破局:量化指标与工程验证 ✅ 破局核心原则(结论先行) 拥有2台以上VPS的独立开发者,多节点资源监控首选Beszel。架构极简( Hub-Agent模式),Hub端用Docker一行启动(内存仅占30MB,默认端口…

1、期望目标

阅读并按本指南实操后,你将达成以下目标:

  • [ ] 在主控服务器上通过 Docker Compose 一键启动 Beszel Hub;
  • [ ] 在被监控节点上安装轻量 Agent,并建立安全的端到端通讯;
  • [ ] 挂载 Docker 套接字,实时展示各微服务容器的资源占用;
  • [ ] 设定 CPU > 80%、磁盘 > 90% 以及节点心跳超时自动告警;
  • [ ] 绑定 Telegram Bot,实现故障告警实时推送到手机;
  • [ ] 使用 Caddy 或 Nginx 配置反向代理与 HTTPS 加密,保护监控看板。
落地执行与验证流水线:期望目标 按序执行以下四步流程,把定性经验转化为可自动巡检的工程防线 STEP 01 基线探测与问题定位 采集真实线上指标与配置 快照 STEP 02 红线过滤与风险隔离 剔除高危配置与低质冗余 资产 STEP 03 标准化加固与重构 注入经过验证的脚本与架 构模板 STEP 04 持续监控与回归审计 接入定时巡检防止问题二 次复发

2、技术架构与横向对比

2.1 Hub-Agent 架构模型

Beszel 轻量化多节点监控拓扑 Beszel Hub 主控中心 PocketBase 后端 (内存 ~30MB) 监听 Web 端口 8090 VPS 1: 业务 Web 站 Beszel Agent (端口 45876) 内存占用不到 10MB VPS 2: API 接口机 Beszel Agent (端口 45876) 监控容器 CPU / 内存 VPS 3: 数据库 / NAS Beszel Agent (端口 45876) 监控磁盘空间与 IO

2.2 常见监控方案量化对比

指标维度 Prometheus + Grafana Netdata Uptime Kuma Beszel (推荐)
主控端内存开销 300MB ~ 800MB 150MB ~ 300MB 80MB ~ 120MB ~30MB
客户端 Agent 开销 50MB ~ 100MB 100MB+ 无 Agent (外部探活) < 10MB
监控指标深度 极深 (全量时序指标) 极深 (秒级细节) 浅 (仅 HTTP/端口存活) 中 (聚焦 CPU/内存/磁盘/Docker)
多服务器汇总看板 需手写 PromQL 与看板 需接入官方云服务 需手动逐个配探针 原生支持多机列表与卡片
部署与上手难度 高 (配置多层文件) 中 低 极低 (5分钟一条命令搞定)

3、在主控 VPS 上部署 Beszel Hub

3.1 创建部署目录与生产级编排文件

选择一台网络连通性较好的 VPS 充当 Hub。创建生产级 docker-compose.yml,配置健康检查与资源硬限制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# ~/beszel/docker-compose.yml
version: '3.8'

services:
beszel-hub:
image: henrygd/beszel:latest
container_name: beszel-hub
restart: unless-stopped
ports:
- "127.0.0.1:8090:8090" # 仅绑定本地回环,强制通过反向代理访问
volumes:
- ./data:/beszel_data
environment:
- TZ=UTC
- APP_URL=https://monitor.yourdomain.com
deploy:
resources:
limits:
cpus: '0.50'
memory: 128M
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:8090/api/health"]
interval: 30s
timeout: 5s
retries: 3

启动主控端服务:

1
2
3
4
mkdir -p ~/beszel/data
cd ~/beszel
docker compose up -d
docker compose ps
底层机制与架构拆解:在主控VPS上部署Beszel Hub 四阶段递进分析模型 · 从前置识别到最终工程定级 S1 创建部署目录与生产级… 选择一台网络连通性较好 的VPS充当Hub。创建生产… S2 底层协议与规则校验 对照核心规范与真实负载 指标逐项核验 S3 瓶颈隔离与风险阻断 剔除干扰链路、单点隐患 与高危配置 S4 确定性架构标准输出 沉淀为可一键复现的工程 配置基线 💡 工程启示:任何一个前置环节失守,都会通过传导链放大为下游的系统性偏差

4、在被监控节点上安装与加固 Beszel Agent

4.1 方案 A:原生 Systemd 服务配置(无 Docker 节点推荐)

在被监控的纯 Linux 主机上,推荐采用原生二进制部署。创建专用运行用户与 systemd unit 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# /etc/systemd/system/beszel-agent.service
[Unit]
Description=Beszel Agent Monitoring Daemon
After=network.target

[Service]
Type=simple
User=root
# 如需监控非 root Docker 容器,确保用户在 docker 组
ExecStart=/opt/beszel-agent/beszel-agent
Restart=always
RestartSec=5
EnvironmentFile=/etc/beszel-agent.env

# 安全沙箱加固参数
ProtectSystem=full
NoNewPrivileges=true
MemoryMax=40M
CPUQuota=10%

[Install]
WantedBy=multi-user.target

创建环境配置文件 /etc/beszel-agent.env:

1
2
3
4
PORT=45876
KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI..." # 从 Hub 控制台生成的 Ed25519 公钥
FILESYSTEM=/dev/root
EXTRA_FILESYSTEMS=

重载并启动 systemd 守护进程:

1
2
3
sudo systemctl daemon-reload
sudo systemctl enable --now beszel-agent
sudo systemctl status beszel-agent

4.2 方案 B:容器化 Agent 部署(Docker 环境)

若目标服务器已部署 Docker 环境,采用 Compose 部署。为了避免直接暴露 root 权限的 Docker 套接字,推荐搭配只读 Socket 代理 tecnativa/docker-socket-proxy 协同运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# ~/beszel-agent/docker-compose.yml
version: '3.8'

services:
# 安全代理层:拦截危险的 Docker API 写入调用,仅放行只读指标查询
docker-proxy:
image: tecnativa/docker-socket-proxy:latest
container_name: docker-socket-proxy
restart: unless-stopped
environment:
- CONTAINERS=1 # 允许读取容器列表
- STATS=1 # 允许读取资源统计
- POST=0 # 严禁任何 POST 修改操作
- DELETE=0 # 严禁删除操作
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- "127.0.0.1:2375:2375"

beszel-agent:
image: henrygd/beszel-agent:latest
container_name: beszel-agent
restart: unless-stopped
network_mode: host # 必须为 host 模式以精准采集宿主机真实网络指标
depends_on:
- docker-proxy
volumes:
- /:/extra-filesystems/root:ro
environment:
- PORT=45876
- KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI..."
- DOCKER_HOST=tcp://127.0.0.1:2375
问题现场解剖:在被监控节点上安装与加固Beszel Agent ⚠️ 从问题出发:表面症状是如何一步步演变为生产故障或降权的? 独立开发者工具箱 · CH-43 · 核心卡点传导链 1. 方案A:原生Systemd服务… 在被监控的纯Linux主机上,推 荐采用原生二进制部署。创建专… 症结:认知偏差与配置盲区 2. 方案B:容器化Agent部署… 若目标服务器已部署Docker环 境,采用Compose部署。为了避… 传导:隐性劣化与边界失守 3. 缺乏验证流程 无量化观测指标与自动化止损防 线 破局:量化指标与工程验证 ✅ 破局核心原则(结论先行) 拥有2台以上VPS的独立开发者,多节点资源监控首选Beszel。架构极简( Hub-Agent模式),Hub端用Docker一行启动(内存仅占30MB,默认端口…

5、网络安全与防火墙收敛规则

千万不要把 Agent 通信端口 45876 对全球 IP 开放。必须严格收紧访问源:

1
2
3
4
5
6
# 仅允许 Hub 主控服务器公网 IP 访问 45876 端口
sudo ufw default deny incoming
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow proto tcp from <HUB_PUBLIC_IP> to any port 45876 comment 'Beszel Hub Poll'
sudo ufw enable
sudo ufw reload

验证防火墙规则生效情况:

1
sudo ufw status verbose
底层机制与架构拆解:网络安全与防火墙收敛规则 四阶段递进分析模型 · 从前置识别到最终工程定级 S1 输入识别与场景分流 明确核心业务诉求与上下 文边界条件 S2 底层协议与规则校验 对照核心规范与真实负载 指标逐项核验 S3 瓶颈隔离与风险阻断 剔除干扰链路、单点隐患 与高危配置 S4 确定性架构标准输出 沉淀为可一键复现的工程 配置基线 💡 工程启示:任何一个前置环节失守,都会通过传导链放大为下游的系统性偏差

6、生产级反向代理与 HTTPS 加固配置

6.1 Caddy 反向代理配置

编辑 /etc/caddy/Caddyfile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
monitor.yourdomain.com {
encode gzip zstd

# 安全响应头
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
}

reverse_proxy 127.0.0.1:8090 {
# 支持长连接与实时 SSE/WebSocket 推送
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}

6.2 Nginx 反向代理配置(含 WebSocket / SSE 支持)

编辑 /etc/nginx/sites-available/beszel.conf:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
server {
listen 80;
server_name monitor.yourdomain.com;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2;
server_name monitor.yourdomain.com;

ssl_certificate /etc/letsencrypt/live/monitor.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/monitor.yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

location / {
proxy_pass http://127.0.0.1:8090;
proxy_http_version 1.1;

# WebSocket 与长轮询升级协议头
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

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;

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
问题整改前后解剖:生产级反向代理与HTTPS加固配置 ⚠️ 整改前:常见踩坑与失分现场 • 盲区 1:忽视「Caddy反向代理配置」边界约束 • 盲区 2:缺乏「Nginx反向代理配置(含…」实测核验 • 盲区 3:遗漏「可验证证据链」兜底监控 后果:线上隐性故障频发 / 评估等级下调 ✅ 整改后:高确定性工程实践 • 动作 1:Caddy反向代理配置:编辑… • 动作 2:Nginx反向代理配置(含WebSocket/SSE支… • 动作 3:可验证证据链:配备实机压测指标、日志与可复… 收益:指标可观测、配置可复现、风险可阻断

7、告警规则与 Telegram 通知配置

单看图表仍属被动运维,必须建立主动通知链路。

7.1 获取 Telegram Bot Token 与 Chat ID

  1. 在 Telegram 搜索并打开 @BotFather,发送 /newbot,按向导命名后获取 BOT_TOKEN(形如 7123456789:AAF-xxxxxxxxxxxxxxxxxxxx);
  2. 打开新建的机器人对话窗口,点击 Start 发送一条初始消息;
  3. 搜索并打开 @userinfobot,发送任意字符获取你个人的 Id(纯数字 Chat ID,例如 123456789)。

7.2 在 Beszel 控制面板配置通知与阈值

进入 Beszel Hub 的 Settings -> Notifications:

  • Provider:选择 Telegram;
  • Token:填入上述 BOT_TOKEN;
  • Chat ID:填入你的用户或群组 Chat ID;
  • 点击 Send Test 按钮,手机端即刻收到测试告警弹窗。

接着在 Alerts 规则中配置黄金防线:

  • CPU Alert:使用率持续 5 分钟超过 85% 报警;
  • Memory Alert:内存使用率超过 90% 报警;
  • Disk Alert:任一挂载磁盘使用率超过 88% 立即报警(留出运维缓冲期);
  • Status Alert:主机失联超过 2 分钟立即报警。
底层机制与架构拆解:告警规则与Telegram通知配置 四阶段递进分析模型 · 从前置识别到最终工程定级 S1 Provider 选择Telegram; 底层规则强约束 S2 Token 填入上述BOTTOKEN; 底层规则强约束 S3 Chat ID 填入你的用户或群组Chat ID; S4 CPU Alert 使用率持续5分钟超过85% 报警; 💡 工程启示:任何一个前置环节失守,都会通过传导链放大为下游的系统性偏差

8、实战排错与常用运维指令

8.1 连通性排查

在 Hub 服务器上执行网络探针,核验与目标节点 Agent 的连通性:

1
2
3
4
5
6
7
8
9
# 测试目标节点 45876 端口连通状态
nc -zv <AGENT_IP> 45876

# 若提示 Connection refused:
# 检查 Agent 节点进程是否存活
sudo systemctl status beszel-agent

# 若提示 Connection timed out:
# 检查目标节点的云厂商安全组 (Security Group) 与 ufw 是否放行该来源 IP

8.2 数据备份与恢复

Beszel Hub 的所有历史监控数据、节点公钥与告警规则均保存在挂载目录下的 PocketBase SQLite 数据库中。可建立每日定时快照:

1
2
3
4
5
# 执行本地热备份
tar -czf ~/beszel-backup-$(date +%Y%m%d).tar.gz -C ~/beszel data

# 结合开源脚本巡检整机健康状态
curl -fsSL https://raw.githubusercontent.com/ittinker/ittinker-scripts/main/vps-health-monitor/vps-health-monitor.sh | bash

8.3 自动化 SQLite WAL 检查与数据库日常维护

Beszel 底层使用 PocketBase (SQLite)。在高并发拉取多节点指标时,建议通过定时脚本检查 WAL 日志体积,防止日志文件失控:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env bash
# ~/beszel/scripts/db-maintenance.sh
set -euo pipefail

DATA_DIR="$HOME/beszel/data"
BACKUP_DIR="$HOME/beszel/backups"
mkdir -p "$BACKUP_DIR"

# 1. 检查 sqlite wal 临时文件体积
WAL_FILE="$DATA_DIR/pb_data/data.db-wal"
if [ -f "$WAL_FILE" ]; then
WAL_SIZE_MB=$(du -m "$WAL_FILE" | cut -f1)
if [ "$WAL_SIZE_MB" -gt 50 ]; then
echo "[WARN] SQLite WAL file exceeded 50MB (${WAL_SIZE_MB}MB). Triggering checkpoint..."
# 通过 sqlite3 发起 passive checkpoint
sqlite3 "$DATA_DIR/pb_data/data.db" "PRAGMA wal_checkpoint(PASSIVE);"
fi
fi

# 2. 轮转保留最近 7 天备份
BACKUP_TAR="$BACKUP_DIR/beszel-backup-$(date +%Y%m%d).tar.gz"
tar -czf "$BACKUP_TAR" -C "$HOME/beszel" data
find "$BACKUP_DIR" -type f -name "beszel-backup-*.tar.gz" -mtime +7 -delete
echo "[OK] Beszel backup complete: $BACKUP_TAR"

配置入 crontab 即可实现每日无人值守备份:

1
2
# 每天凌晨 03:30 执行维护脚本
(crontab -l 2>/dev/null; echo "30 3 * * * /bin/bash $HOME/beszel/scripts/db-maintenance.sh >> $HOME/beszel/maintenance.log 2>&1") | crontab -

至此,一套内存总占用不到 50MB 的多服务器自动化监控与告警中心已全部交付上线。

问题整改前后解剖:实战排错与常用运维指令 ⚠️ 整改前:常见踩坑与失分现场 • 盲区 1:忽视「连通性排查」边界约束 • 盲区 2:缺乏「数据备份与恢复」实测核验 • 盲区 3:遗漏「自动化SQLite WAL检查与…」兜底监控 后果:线上隐性故障频发 / 评估等级下调 ✅ 整改后:高确定性工程实践 • 动作 1:连通性排查:在Hub服务器上执行网络探针,核… • 动作 2:数据备份与恢复:Beszel Hub的所有历史监控… • 动作 3:自动化SQLite WAL检查与数据库日常维护… 收益:指标可观测、配置可复现、风险可阻断