这是《多 VPS 统一监控》系列的第二篇。第一篇讲了技术路线:Beszel 负责看机器内部(CPU、内存、磁盘、容器),Uptime Kuma 负责从外部敲门,Portainer 负责动手管容器。这篇讲 Beszel 的 Hub 怎么部署:一个 compose 文件一把拉起三个服务、Nginx 反代、HTTPS 证书。
先把 Hub 跑起来
Beszel 分两部分:Hub(汇总看板,装在博客主机上)和 Agent(装在每台被监控的机器上,负责上报数据)。Hub 用 Docker 跑,一个 compose 文件一把拉起——我把三个监控服务写在同一个文件里,省得满世界找:
在博客主机上新建目录和 docker-compose.yml(下面三个镜像和端口就是我当时用的;数据卷按各镜像官方惯例挂载):
mkdir -p /home/docker/monitoring && cd /home/docker/monitoring
# /home/docker/monitoring/docker-compose.yml
services:
beszel:
image: henrygd/beszel:latest
container_name: beszel
ports:
- "127.0.0.1:8090:8090" # 只绑本机,不暴露到公网
volumes:
- ./beszel_data:/beszel_data
restart: unless-stopped
uptime-kuma:
image: louislam/uptime-kuma:2
container_name: uptime-kuma
ports:
- "127.0.0.1:3001:3001"
volumes:
- ./uptime-kuma:/app/data
restart: unless-stopped
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
ports:
- "127.0.0.1:9000:9000"
- "127.0.0.1:9443:9443"
- "127.0.0.1:8000:8000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./portainer_data:/data
restart: unless-stopped
注意两点:一是 Uptime Kuma 要用 :2 这个 tag——:1(当时默认的 latest 指向的 v1.23.17)已经停止维护,没有安全更新,我中途还为此升过一次级;二是三个服务的端口都只绑了 127.0.0.1,公网直接访问不了,这是故意的,入口统一走 Nginx 反代。
docker compose up -d
# 本机验证三个服务都起来了
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8090 # Beszel,应 200
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:3001 # Kuma,应 302
curl -sk -o /dev/null -w "%{http_code}\n" https://127.0.0.1:9443 # Portainer,应 200
Nginx 反代 + HTTPS
博客主机用的是 kejilion.sh 的 LDNMP,Nginx 配置在 /home/web/conf.d/。给三个面板各写一个 vhost,以 Beszel 为例(monitor.nettodata.com.conf):
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name monitor.nettodata.com;
ssl_certificate /home/web/certs/monitor.nettodata.com_cert.pem;
ssl_certificate_key /home/web/certs/monitor.nettodata.com_key.pem;
location / {
proxy_pass http://127.0.0.1:8090;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# WebSocket 支持(面板实时刷新用)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# ACME 验证路径(证书续签用)
location ^~ /.well-known/acme-challenge/ {
root /home/web/html/nettodata.com/wordpress;
}
}
server {
listen 80;
server_name monitor.nettodata.com;
return 301 https://$host$request_uri;
}
流程是:先在 Cloudflare 给 monitor / status / manage 三个子域名加 DNS-only 的 A 记录指向 VPS 公网 IP,等 DNS 生效后用 certbot(或你面板自带的签发脚本)签 ECDSA 证书,证书放到 /home/web/certs/,vhost 里引用,nginx -t 通过后 reload。签好后用公网 curl 验证:Beszel 应返回 200,Uptime Kuma 302 跳到 dashboard,Portainer 307。
证书续签不用操心:VPS 上已有一条每天凌晨跑的 0 0 * * * ~/auto_cert_renewal.sh,会把这几个新证书一起续上。
下一篇
下一篇《多 VPS 统一监控(三):Beszel(二)Agent 接入与告警》讲四台机器装 Agent 的全过程、我踩过的三个坑,以及 12 条告警规则和 Bark 推送是怎么配的。