云端部署

Docker:用 Compose 搭建家庭实验室入口与监控面板

用一个 Compose 文件在家里的小主机上搭建家庭实验室入口:Homepage 做导航首页,Uptime Kuma 监控各个服务是否在线并发通知,Caddy 做反向代理并自动签发局域网 HTTPS 证书,访问 https://home.lan 和 https://status.lan 即可。

BINBHO · 图文教程

用一个 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 的监控和通知。