❤️🩹 阅读本篇文章之前建议先完成这篇:搭建简易家庭IT实验室——监控平台。
C 缘起
感谢Grafana,我免费使用它的云服务好几年了,功能强大,性能够用,还一直免费,真的很好。
但是随着我的赛博过家家越来越复杂,内容一年比一年多,Grafana的免费额度对我来说越发捉襟见肘。付费是不可能付费的,这辈子都不会付费,只有去哪薅个服务器回来才能勉强维持得了生活这样子。
要想解决也很简单,不想使用云服务,那么我可以自建相应的服务。
Prometheus家用示意图
我只要把上图右边云里的服务用自建代替即可。其他部分能不动就不动。
正好我有台闲置的VDS,吃灰好几年了,拿出来玩玩。
D 配置
VictoriaMetrics
既然是自己玩,这次就不在公网用Prometheus了,VictoriaMetrics(简称VM,下同)是乌克兰人开发的软件,性能好,功能多,毛子在软件这块就是令人信服。VM的功能虽然多,但是我暂时只用一点,就是它全面兼容Prometheus的API。
安装清单
| 组件 |
推荐软件 |
说明 |
| 容器编排 |
Docker Compose |
方便管理多个服务(Grafana, VM, Node-Exporter)。 |
| 数据库 |
VM (单机版)) |
替代Grafana官方云的后端存储,接收 remote_write 数据。 |
| 展示层 |
Grafana OSS |
添加 VM 作为数据源。 |
| 反向代理 |
Nginx / Caddy |
为 Grafana 提供域名访问和 SSL 证书(HTTPS)。 |
我需要一个Grafana免费版,一个VM,一个Caddy和一个Docker Engine。
数据流向
- 我家里的Node-Exporter去读取Linux的性能数据。
- 家里的Prometheus读取(刮削)家里的Node-Exporter。
- 家里的Prometheus推送数据到VDS上跑的VM。
- VDS上跑的Grafana读取VDS上跑的VM的数据。
E 安装
Docker
先准备一个文件夹(我是喜欢Caddy单独跑的,假如您喜欢用Docker跑也可以在这建立子文件夹):
1
2
3
|
mkdir -p ~/monitoring/data/{victoriametrics,grafana}
# 或者 mkdir -p ~/monitoring/data/{victoriametrics,grafana,caddy}
cd ~/monitoring
|
然后准备编写文件(nano 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
|
services:
# VictoriaMetrics
victoriametrics:
container_name: victoriametrics
image: victoriametrics/victoria-metrics:latest
restart: always
volumes:
- ./data/victoriametrics:/storage
ports:
- '127.0.0.1:8428:8428'
command:
- "--storageDataPath=/storage"
- "--retentionPeriod=1y"
- "--httpListenAddr=:8428"
# Grafana
grafana:
container_name: grafana
image: grafana/grafana-oss:latest
restart: always
environment:
- GF_SERVER_ROOT_URL=https://grafana.miyunda.com/
volumes:
- ./data/grafana:/var/lib/grafana
ports:
- '127.0.0.1:3000:3000'
|
⚠️ 注意端口一定不要绑在0.0.0.0上面,很难受。
喜欢用Docker跑Caddy的点这里
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
33
34
35
36
37
38
39
40
|
services:
# VictoriaMetrics
victoriametrics:
container_name: victoriametrics
image: victoriametrics/victoria-metrics:latest
restart: always
volumes:
- ./data/victoriametrics:/storage
ports:
- '127.0.0.1:8428:8428'
command:
- "--storageDataPath=/storage"
- "--retentionPeriod=1y"
- "--httpListenAddr=:8428"
# Grafana
grafana:
container_name: grafana
image: grafana/grafana-oss:latest
restart: always
environment:
- GF_SERVER_ROOT_URL=https://grafana.miyunda.com/
volumes:
- ./data/grafana:/var/lib/grafana
ports:
- '127.0.0.1:3000:3000'
# Caddy
caddy:
container_name: caddy
image: caddy:latest
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./data/caddy_data:/data
- ./data/caddy_config:/config
- ./data/caddy_log:/var/log/caddy
|
设置验证密码
我的VM当然不能随便来人就能推数据,得用个密码保护起来。VM自带很多功能,其中就包括vm_auth,我是不想研究那么多,就想弄个最简单的就行。我决定用Caddy自带的密码验证。
先想一个密码,然后下面命令会搞一个哈希值出来,也存起来。
1
2
3
|
caddy hash-password --plaintext <密码>
或者
docker run --rm caddy caddy hash-password --plaintext <密码>
|
ℹ️ 现代加密哈希算法在处理密码时会自动引入一个盐值(Salt),所以每次输入相同的密码也会得到不同的哈希值。
配置Caddy
1
2
3
|
sudo nano /etc/caddy/Caddyfile
或者
nano Caddyfile
|
它的内容类似这样:
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
|
{
acme_ca https://acme.zerossl.com/v2/DV90
email <ZeroSSL的注册邮件>
}
(log-common) {
log {
output file /var/log/caddy/{args[0]}.log {
mode 0664
roll_size 10mb
roll_keep 20
roll_keep_for 30d
}
}
}
victoriametrics.miyunda.com {
basic_auth {
push_homelab "$2a$14$L5马赛克马赛克马赛克Ts6NCRMjfFgLsy"
}
reverse_proxy 127.0.0.1:8428
import log-common victoriametrics
}
grafana.miyunda.com {
import log-common grafana
reverse_proxy 127.0.0.1:3000
}
|
其中push_homelab那里可以搞多行,每行一个用户名密码——以后有多个数据来源时可以更容易分辨,理论上也更安全。
对外服务的域名那里换成您自己的。
前四行可以不要,Caddy默认的ACME是Let’s Encrypt,我只是更喜欢ZeroSSL而已。(套Cloudflare的话还有谷歌或者Let’s Encrypt签发的证书)
127.0.0.1使用Docker运行Caddy可以把这里换成容器名,利用Docker提供的内部解析。
另:Caddy 版本<v2.8.0的话是不支持basic_auth的,独立运行的可能得升级Caddy版本。用Docker运行Caddy的话没有这个烦恼。下面以Debian为例安装新版本Caddy:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
caddy version
sudo apt remove caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy
caddy version
sudo mkdir -p /var/log/caddy
sudo chown caddy:caddy /var/log/caddy
sudo chmod 2750 /var/log/caddy
sudo usermod -aG caddy $USER
newgrp caddy
|
Cloudflare (可选,建议)
为了防止别人知道我们的服务器的真实地址,同时尽可能提升访问速度,我们请出赛博菩萨——Cloudflare。
此处需要先将您的域名解析(NS)委托给Cloudflare,请自行完成。
先去Cloudflare的Web控制台给您的两个网站建好CNAME记录,并开启代理。
然后去创建一个配置规则(Configuration Rule)。该规则的核心目的是针对 ACME HTTP-01 挑战(自动申请您的SSL证书)禁用“自动HTTPS重写”,以确保验证过程不被强制跳转干扰。
- 基础信息设置
- 规则名称: 输入一个易于识别的名称,例如
allow acme http-01。
- 匹配条件设置 (If incoming requests match…)
我们需要筛选出所有指向证书验证路径的请求:
- 选择模式: 选中 Custom filter expression。
- 字段 (Field): 下拉选择
URI Path。
- 运算符 (Operator): 选择
contains(包含)。
- 值 (Value): 输入
/.well-known/acme-challenge/*。
注意: 预览框中显示的表达式应为:(http.request.uri.path contains "/.well-known/acme-challenge/*")。
- 操作设置 (Then the settings are…)
在下方找到具体的设置选项,调整 Cloudflare 对匹配请求的处理方式:
- Automatic HTTPS Rewrites (自动 HTTPS 重写): 将开关拨至 关闭 (Off) 状态。
如图:

这样就可以避免基于HTTP 80端口的挑战流量被Cloudflare重定向到HTTPS 443端口。
启动
1
2
|
docker-compose up -d
sudo systemctl start caddy #独立运行的Caddy
|
试试
尝试在服务器上访问两个容器,回应应该都是200:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
curl -I http://127.0.0.1:8428/metrics
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Vary: Accept-Encoding
X-Server-Hostname: 4372bbd36de6
Date: Sun, 08 Mar 2026 15:07:03 GMT
curl -I http://127.0.0.1:3000/login
HTTP/1.1 200 OK
Cache-Control: no-store
Content-Type: text/html; charset=UTF-8
X-Content-Type-Options: nosniff
X-Frame-Options: deny
X-Xss-Protection: 1; mode=block
Date: Sun, 08 Mar 2026 15:02:50 GMT
|
有什么不对的话可以看看有没有侦听,也看看日志:
1
2
3
|
sudo ss -tulpn
docker logs grafana
docker logs victoriametrics
|
这时应该可以从外网访问两个新域名试试了。
F 使用
VM
用浏览器打开VM的域名,输入用户名密码之后可以查询数据库,不会查询的可以去看仪表板(Dashboards)。
家里的Prometheus
编辑家里的Prometheus配置文件,找到这样的几行:
1
2
3
4
|
- url: https://prometheus-prod-10-prod-us-central-0.grafana.net/api/prom/push
basic_auth:
username: 888898
password: glc_eyJvIjoi马赛克马赛克马赛克DQ1ZURyTVkiLCJtIjp7InIiOiJ1cyJ9fQ==
|
把他们都注释掉。然后在remote_write:下面添加这样的几行:
1
2
3
4
|
- url: https://<您自己的VM的FQDN>/api/v1/write
basic_auth:
username: <用户名>
password: <密码>
|
然后重启服务即可:
1
2
3
|
sudo systemctl restart prometheus
sudo systemctl status prometheus
sudo journalctl -u prometheus -f
|
exporter那些不用动,因为没有变化,只是推送的去处从云服务变成自建的。
看看有没有收到数据
在VM的Web界面左上角的查询输入框里输入下面任意一条 PromQL 查询,然后点 Execute(或回车),这里的"jobname"必须存在于家里的Prometheus的配置文件中的scrape_configs:的 - job_name:里面。
下图为我家某个路由器的累计CPU时间。

也可以访问https://<VM的FQDN>/vmui/#/metrics,这里能浏览所有jobname。
Grafana
浏览器访问Grafana的FQDN,先创建用户名密码,不多说了。
数据源
然后添加一个数据源,其中类型为Prometheus!!! 不要选VictoriaMetrics !!!
地址填容器名和端口就行了——比回环地址好看点。
如图:

仪表板
这个不多说了,原来在官方云上添加的仪表板,现在添加到自建的,是一样的,可以去https://grafana.com/grafana/dashboards/查看。
如图,一个闲置的小主机,安装了几个虚拟机玩过家家用的。

好了,看过就等于会了。感谢观看🥰
接下来还将加入收集日志的功能,敬请期待。