用一个 Compose 文件在家里的小主机上搭建家庭实验室入口:Homepage 做导航首页,Uptime Kuma 监控各个服务是否在线并发通知,Caddy 做反向代理并自动签发局域网 HTTPS 证书,访问
https://home.lan和https://status.lan即可。
先看清成品
成品是一个首页面板,显示主机 CPU、内存、磁盘和时间,下面是家里各个服务和设备的入口卡片,在线状态和响应时间实时显示。本文配置已在 Linux 上实际运行:三个容器正常启动,
https://home.lan返回 200 并截图确认面板正常显示,https://status.lan跳转到 Uptime Kuma 的初始化页面,HTTP 自动跳转 HTTPS。局域网 DNS 和路由器设置没有在测试环境中操作。
做完之后你会得到什么?
| 成果 | 说明 |
|---|---|
| 导航首页 | Homepage,集中所有服务入口 |
| 状态监控 | Uptime Kuma,服务掉线时推送通知 |
| 反向代理 | Caddy,用域名代替“IP + 端口” |
| 局域网 HTTPS | Caddy 内部 CA 自动签发证书 |
| 一个 Compose 文件 | 全部服务一条命令启停 |
需要准备哪些硬件和环境?
| 项目 | 建议 | 说明 |
|---|---|---|
| 主机 | 迷你主机、旧笔记本、树莓派 4/5 | 三个服务都很轻量 |
| 系统 | Ubuntu Server 或 Debian | 装好 Docker 和 Compose 插件 |
| 网络 | 有线连接路由器 | 在路由器里给主机分配固定 IP |
| 端口 | 80、443 空闲 | Caddy 需要 |
| DNS | 路由器或 AdGuard Home 等支持自定义解析 | 把 home.lan 指向主机 |
下文假设主机固定 IP 为 192.168.1.5,换成你自己的地址。
第一步:项目结构是什么样的?
homelab/
├── compose.yaml
├── caddy/
│ └── Caddyfile
└── homepage/
├── settings.yaml
├── services.yaml
├── widgets.yaml
└── bookmarks.yaml
1. 让 AI 帮你列服务清单(可选)
我家里有这些设备和服务:路由器 192.168.1.1、NAS 192.168.1.10:5000、Jellyfin 192.168.1.20:8096。
请帮我写 Homepage 的 services.yaml,分成“服务”和“设备”两组,
每个条目包含 href、中文 description、icon,网页服务加上 siteMonitor。
第二步:Compose 和 Caddy 怎么写?
1. compose.yaml
services:
caddy:
image: caddy:2.11
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
restart: unless-stopped
homepage:
image: ghcr.io/gethomepage/homepage:v2.6.0
environment:
HOMEPAGE_ALLOWED_HOSTS: home.lan
volumes:
- ./homepage:/app/config
restart: unless-stopped
uptime-kuma:
image: louislam/uptime-kuma:2
volumes:
- kuma_data:/app/data
restart: unless-stopped
volumes:
caddy_data:
caddy_config:
kuma_data:
只有 Caddy 映射了端口,Homepage 和 Uptime Kuma 只在 Docker 内部网络里可见,所有访问都经过 Caddy。
2. caddy/Caddyfile
# 局域网内用 Caddy 自带的内部 CA 签发 HTTPS 证书
{
local_certs
}
home.lan {
reverse_proxy homepage:3000
}
status.lan {
reverse_proxy uptime-kuma:3001
}
| 配置 | 作用 |
|---|---|
local_certs |
所有站点使用 Caddy 自己的内部 CA 签证书,不去申请公网证书 |
home.lan |
访问这个域名时转发到 Homepage |
reverse_proxy 服务名:端口 |
Compose 服务名就是内部主机名 |
.lan 不是公网域名,只在家里 DNS 解析时有效,所以用内部证书。
第三步:Homepage 怎么配置?
1. settings.yaml
title: 我的家庭实验室
language: zh-CN
theme: dark
color: slate
layout:
服务:
style: row
columns: 3
设备:
style: row
columns: 3
2. services.yaml
- 服务:
- 服务监控:
href: https://status.lan
description: Uptime Kuma,服务挂了第一时间知道
icon: uptime-kuma.png
siteMonitor: http://uptime-kuma:3001
- 媒体库:
href: http://192.168.1.20:8096
description: Jellyfin(示例地址,换成你自己的)
icon: jellyfin.png
siteMonitor: http://192.168.1.20:8096
- 设备:
- 路由器:
href: http://192.168.1.1
description: 家里的主路由
icon: router.png
- NAS:
href: http://192.168.1.10:5000
description: 文件存储
icon: synology.png
siteMonitor 由 Homepage 服务端去探测地址,卡片右上角显示响应时间或离线。
3. widgets.yaml
- resources:
cpu: true
memory: true
disk: /
- datetime:
text_size: xl
format:
dateStyle: long
timeStyle: short
bookmarks.yaml 可以留空。
4. 关于 HOMEPAGE_ALLOWED_HOSTS
Homepage 要求设置这个环境变量,值是你在浏览器地址栏里访问它用的主机名。经 Caddy 访问时填 home.lan;没有设对会拒绝访问。
第四步:怎样启动和配置 DNS?
1. 启动
docker compose up -d
docker compose ps
2. 先用命令行验证
DNS 还没配时,可以用 --resolve 模拟解析:
curl -sk --resolve home.lan:443:127.0.0.1 https://home.lan -o /dev/null -w "%{http_code}\n"
curl -sk --resolve status.lan:443:127.0.0.1 https://status.lan -o /dev/null -w "%{http_code}\n"
本文实际输出:home.lan 返回 200,status.lan 返回 302(跳转到 Uptime Kuma 的设置页面),访问 http://home.lan 返回 308 跳转到 HTTPS。
3. 配置局域网 DNS
在路由器或家里的 DNS 服务里添加两条解析:
| 域名 | 指向 |
|---|---|
home.lan |
192.168.1.5 |
status.lan |
192.168.1.5 |
暂时没法改路由器时,可以在电脑的 hosts 文件里加:
192.168.1.5 home.lan status.lan
4. 信任内部证书
浏览器第一次访问会提示证书不受信任。导出 Caddy 的根证书:
docker compose cp caddy:/data/caddy/pki/authorities/local/root.crt ./caddy-root.crt
把 caddy-root.crt 导入电脑或手机的“受信任的根证书”。只在你自己的设备上导入。
5. 检查结果
| 检查项 | 通过标准 |
|---|---|
https://home.lan |
显示首页,没有证书警告 |
| 资源卡片 | 顶部显示 CPU、内存、磁盘 |
| 服务卡片 | 右上角显示响应时间或离线 |
https://status.lan |
打开 Uptime Kuma 设置向导 |
本文截图中,“服务监控”卡片显示了响应时间,示例 Jellyfin 地址不存在所以显示离线,这符合预期。图标从网络加载,网络不通时卡片不显示图标。
第五步:怎样设置监控和通知?
1. 初始化 Uptime Kuma
打开 https://status.lan,按向导选择数据库类型并创建管理员账号。
2. 添加监控项
| 名称 | 类型 | 地址 |
|---|---|---|
| 首页 | HTTP(s) | http://homepage:3000 |
| 路由器 | Ping | 192.168.1.1 |
| NAS | HTTP(s) | http://192.168.1.10:5000 |
| Jellyfin | HTTP(s) | http://192.168.1.20:8096/health |
容器内的服务用 Compose 服务名访问;局域网设备用 IP。
3. 配置通知
在 设置 → 通知 里添加通知方式,Uptime Kuma 支持邮件、Telegram、钉钉、企业微信等多种渠道。添加后点“测试”确认能收到消息,再在每个监控项里勾选。
注意:Uptime Kuma 管理员账号能看到你家里全部设备的地址,务必设置强密码,不要把 80/443 端口映射到公网。
出问题时该怎么调?
1. Homepage 显示 Host validation failed
HOMEPAGE_ALLOWED_HOSTS 和浏览器访问的主机名不一致。用 IP 加端口访问时也要把它加进去,多个值用逗号分隔。
2. 浏览器提示连接被拒绝
| 检查 | 命令 |
|---|---|
| Caddy 是否运行 | docker compose logs caddy --tail 30 |
| 80/443 是否被占用 | `sudo ss -tlnp |
| DNS 是否生效 | nslookup home.lan 应返回主机 IP |
3. 修改 Caddyfile 后不生效
docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile
4. 想显示 Docker 容器状态
Homepage 支持挂载 /var/run/docker.sock 读取容器状态。官方文档提醒直接挂载 socket 不是推荐做法,因为它相当于给了容器宿主机的管理权限。确实需要时,用只读挂载,或改用 docker-socket-proxy 只开放必要接口。
常见问题怎么处理?
| 现象 | 原因 | 解决方法 |
|---|---|---|
| 证书警告一直存在 | 根证书没导入或导入错位置 | 导入到“受信任的根证书颁发机构” |
手机访问不了 .lan |
手机用了自定义 DNS | 关闭手机私人 DNS,或在该 DNS 里加解析 |
| 卡片一直显示离线 | 地址对 Homepage 容器不可达 | 在容器里 docker compose exec homepage wget -qO- 地址 测试 |
| 修改 YAML 后报错 | 缩进错误 | 用空格缩进,不要用 Tab |
| Uptime Kuma 数据丢失 | 删除了数据卷 | 不要执行 down -v,定期备份 kuma_data |
| 升级后配置不兼容 | 跨大版本 | 固定版本标签,升级前读发布说明 |
项目资源
| 用途 | 地址 |
|---|---|
| Homepage 文档 | https://gethomepage.dev/ |
| Homepage Docker 安装 | https://gethomepage.dev/installation/docker/ |
| Homepage 服务配置 | https://gethomepage.dev/configs/services/ |
| Uptime Kuma 仓库 | https://github.com/louislam/uptime-kuma |
| Caddyfile 文档 | https://caddyserver.com/docs/caddyfile |
| Caddy 自动 HTTPS | https://caddyserver.com/docs/automatic-https |
| Caddy Docker 镜像 | https://hub.docker.com/_/caddy |
| Compose 文件参考 | https://docs.docker.com/reference/compose-file/ |
建议先在一台电脑上跑起来,用 hosts 文件把 home.lan 指向本机,确认首页能打开。
然后再迁移到常开的小主机,配置路由器 DNS,最后添加 Uptime Kuma 的监控和通知。