# 2K 大屏最终形态：Homepage + Netdata + 自用 WebKit kiosk

- **日期**：2026-09-27
- **硬件**：GPU 机 zywpc（2560×1440，显示器接 **Intel 核显** HDMI，独显纯计算）
- **目标**：一屏同时看到 **GPU · CPU · 内存 · 端口存活 · 时间 · 温度**，不用手搓 TUI

## 一、最终架构（为什么是这个组合）

```
┌─ 自用 WebKitGTK kiosk（cage + kiosk-webkit.py，零 UI 全屏）
│   └─ http://127.0.0.1:3000  Homepage 2.4.0（Docker，配置驱动）
│        ├─ datetime 信息组件  → 东八区大时钟/日期（北京时间）
│        ├─ glances 信息组件   → 宿主机 CPU / 内存 / 磁盘 / 温度 / 运行时长
│        ├─ customapi 卡片     → GPU 利用率·显存·温度·功耗（读本机小 API）
│        ├─ customapi 卡片     → 端口存活 UP/DOWN（读本机小 API）
│        └─ 服务卡片 + siteMonitor → 彩色状态点（ComfyUI/LLM/LM Studio/H3/Netdata）
├─ 本机小 API：homelab-metrics.py（:8787，扁平 JSON 适配层，systemd 托管）
├─ Glances web：glances-web.service（:61208，宿主机指标，systemd 托管）
└─ Netdata 2.11.1（:19999，GPU 13 图 + 端口 18 图 + 温度，做深度下钻与历史）
```

**为什么不用单一工具**：没有哪个成熟项目同时覆盖"系统指标 + 端口存活 + 时钟日历"。
MagicMirror 时钟日历最强但系统统计模块停更；Homarr/Dashy 无 GPU；Homepage 指标要靠
`glances`/`customapi` 拼。所以采**面板层（Homepage）+ 指标源（Glances/自用 API/Netdata）**。

## 二、本次修掉的问题（都踩过）

| 现象 | 根因 | 修法 |
|---|---|---|
| 时钟显示 UTC（差 8 小时） | Homepage 的 datetime 是**浏览器端**渲染，浏览器进程时区=系统时区=UTC | `timedatectl set-timezone Asia/Shanghai`（系统级） |
| Homepage 页面**完全没样式** | **qutebrowser 的 Qt5 WebEngine 太老**，扛不住 Next.js 16 的现代 CSS/JS | 弃用 qutebrowser；改用 epiphany 同款 **WebKitGTK 4.1** |
| epiphany 渲染正常但**带标题栏/地址栏** | epiphany 无 kiosk 开关（`-a` 要 `.desktop` 文件），cog 不在源里 | 自写 **kiosk-webkit.py**（十几行：GTK 无装饰窗口 + WebView + 全屏 + 缩放） |
| `python3 -c "from gi.repository import WebKit2"` 报 Namespace 不可用 | 缺 GI 绑定 | `apt install gir1.2-webkit2-4.1` |
| 中文显示成方块 | 系统无 CJK 字体 | `apt install fonts-noto-cjk` |
| Glances web 起不来：`Bottle module not found` | Ubuntu 的 glances 包不依赖 bottle | `apt install python3-bottle` |
| 每次 `pkill -f <模式串>` 命令静默不执行 | 模式串出现在**自己的命令行**里 → 自杀（本次又中了两次） | 一律 `pkill -x <进程名>`，或让模式串不与命令行重复 |
| `SUDO tee <<EOF` 写进去的是密码 | `SUDO()` 用管道喂密码，heredoc 被顶掉 | 本地写文件 → scp → `install -m` |

## 三、大屏上现在能看到什么（实测截图见 `screenshots/`）

- 右上：**2026年9月27日星期日 21:59:40**（东八区）
- 左上：Glances 宿主机概览 — CPU 10% / Load 3% / 内存 **24.9/30.9 GiB** / 磁盘 **88.2/1.23 TB** / **TEMP 63.5°C** / 运行 1h
- 资源组三张卡：
  - **主机**：CPU 3% · CPU温度 57°C · 内存 19% · 根分区 93%
  - **GPU**：RTX 5060 TI · 利用率 0% · 显存 76% · GPU温度 61°C · 功耗 32W
  - **端口存活**：8189 **UP** · 8080/1234/3013/6020 DOWN
- 服务组：ComfyUI 🟢 · LLM 推理 🔴 · LM Studio 🔴 · H3 Studio 🔴 · Netdata 🟢 · 控制台面板

## 四、日常操作

```bash
display-mode kiosk webkit   # 2K 屏放大屏（cage + kiosk-webkit.py + Homepage），当前模式
display-mode console        # 回 btop 文本面板
display-mode status         # 看模式与各服务状态

# 大屏要显示别的东西：改 ~/.kiosk-url 后重启大屏，例如
echo http://127.0.0.1:19999/ > ~/.kiosk-url     # 换成 Netdata
display-mode kiosk webkit                        # 生效

# 改大屏内容：编辑 ~/homepage/config/{settings,widgets,services,custom}.css|yaml
sudo docker restart homepage                     # 配置热加载，但 custom.css 建议重启
```

## 五、还能继续做的（按性价比排序）

1. **填满下半屏**：把 DSH 机（192.168.31.76）的服务也加进来 —— 下载中心 8899、相册 8900、
   酒馆 8000、DSH Web 3080，都是 `siteMonitor: http://192.168.31.76:xxxx` 一行搞定。
2. **天气 + 户外温度**：Homepage `openmeteo` 组件（需经纬度）。
3. **整月日历**：Homepage/MagicMirror 的 calendar 都是 ICS 议程订阅，没有"月历格子"组件；
   要月历得在自定义页里补一个纯 JS 月历（约 20 行）。
4. **要更"大屏感"**：换 Grafana（社区看板 1860 + 12239）+ clock/calendar 插件，图表最强但组件最多。

## 六、文件与脚本（本目录 `scripts/`）

| 文件 | 作用 |
|---|---|
| `homelab-metrics.py` + `homelab-metrics.service` | :8787 扁平 JSON 适配层（GPU/CPU/内存/磁盘/温度/端口） |
| `glances-web.service` | :61208 宿主机 Glances API（Homepage glances 组件的数据源） |
| `kiosk-webkit.py` | 自用 WebKitGTK 全屏 kiosk 浏览器 |
| `netdata-kiosk.sh` | 大屏启动器（cage + 浏览器，支持 URL/刷新/缩放） |
| `homepage-settings.yaml` / `homepage-widgets.yaml` / `homepage-services.yaml` / `homepage-custom.css` | Homepage 配置 |
| `deploy-homepage.sh` / `deploy-polish.sh` / `pull-homepage.sh` | 部署脚本（含镜像源回退） |
| `display-mode.sh` | kiosk / console 一键切换 |

---

## 七、补：环形/柱状/折线图 —— 社区的标准配法（2026-09-27 追加）

**结论：Homepage 的图表不是靠 `resources`，而是靠 `type: glances` 的 `metric:` 参数**（官方文档
`docs/widgets/services/glances.md`）。它支持这些 metric，全部渲染为**面积/折线图**（另可 `chart: false` 切成无图紧凑视图）：

| metric 写法 | 内容 |
|---|---|
| `cpu` | CPU 使用率折线 |
| `memory` | 内存使用折线（Used/Free/Total） |
| `sensor:Package id 0` | **指定温度传感器**折线（含 Warn/Crit 阈值线） |
| `network:enp2s0` | 网卡 RX/TX 折线 |
| `disk:<盘符>` | 磁盘 I/O 折线 |
| `fs:/` | 挂载点用量（进度条） |
| `gpu:0` | GPU 使用（**本机 Glances 的 gpu 插件取不到 NVML 数据，返回 `[]`**，故 GPU 趋势走 Netdata） |
| `process` | CPU 占用 Top5 进程 |

可直接抄的配置（`config/services.yaml`，这些条目**不需要** href/icon/description）：

```yaml
- 图表监控:
    - CPU 使用率:
        widget:
          type: glances
          url: http://127.0.0.1:61208
          metric: cpu
          pointsLimit: 20
          refreshInterval: 2000
    - CPU 温度:
        widget:
          type: glances
          url: http://127.0.0.1:61208
          metric: "sensor:Package id 0"
```

实测效果见 `screenshots/2026-09-27-2K大屏-图表监控.png`：CPU/内存/CPU温度/网络/磁盘 五张面积图 +
Top5 进程，配上面的大时钟与 Glances 概览，整屏填满。

### 环形图（真正的圆环 gauge）怎么办
- Homepage 的 `resources` **信息组件**是圆环样式，但它在 Docker 里读的是**容器自己的 /proc**（官方文档明说
  "cpu and memory resource information are the container's usage"），要拿宿主机指标得用 `glances` 组件
  （我们已配，样式是"概览 + 条形"而非圆环）。
- 想要**圆环 + 柱状 + 折线**全套，社区的成熟答案是 **Grafana + 社区看板**：
  [Node Exporter Full (1860)](https://grafana.com/grafana/dashboards/1860/)（1.458 亿次下载）里有 gauge/bar gauge/timeseries，
  [NVIDIA DCGM (12239)](https://grafana.com/grafana/dashboards/12239/)（4057 万次）管 GPU；挂墙用官方
  [grafana-kiosk](https://github.com/grafana/grafana-kiosk) + Playlist 轮播。代价：组件最多（Grafana 不在 apt 源）。
