前阵子给家里的 NAS 和服务器装了十几个服务之后,我发现最大的问题不是服务不够用,而是每次想看点什么都要打开一大堆标签页,时间、天气、RSS、系统负载这些信息散落得到处都是。后来我把目光放在了一种叫“个人仪表盘”的小工具上,想着把所有关键信息聚到一个页面里。试过几个方案之后,我留下来了 Honey——一个轻量、本地优先、Docker 部署非常方便的开源个人仪表盘。它主要做四件事:显示时间天气、聚合 RSS 订阅、展示宿主机系统负载、附带一个可以自己扩展的 API 接口。如果你也想要一个不占资源、不折腾的服务器信息入口,这篇实战记录基本可以照着抄。
1. 部署之前,先弄懂 Honey 这个项目在设计上的取舍
很多人在看到一个陌生项目时,第一反应就是先跑起来再说。我的习惯是反过来,先花十分钟搞清楚它到底在解决什么问题,部署的时候才能少踩坑。Honey 这个项目听起来是个新面孔,但它背后的思路其实很清晰:把你日常打开浏览器时最常看的那几类信息,统一放到一个自托管的页面里,同时保证整个过程足够轻。
1.1 它不是一个重平台,而是一个“信息聚合页”
我见过不少个人仪表盘类项目,一上来就绑定了一整套生态,什么用户系统、插件市场、通知中心全给你安排上。配置起来确实香,但如果你只是想在自己电脑或小服务器上看一个简洁的首页,这些功能反而是负担。
Honey 的设计取向恰恰相反,它的核心就是一个后端进程加一个前端页面,后端负责拉取数据、转成 JSON 喂给前端,前端负责把数据渲染成一个干净的自适应页面。整个过程没有数据库依赖,也没有 Redis 之类的中间件,你把它理解成一个“带定时抓取功能的静态页面”就行。这种设计的直接好处是资源占用极低,跑在树莓派或者老笔记本上都没有压力。
另外一个我很看重的点是隐私。天气数据可以走你自选的 API,翻译能力也能接你自己的 Key,RSS 订阅内容直接存在本地,数据不经过任何第三方平台。对自托管玩家来说,这种“数据留在自家机器上”的属性比单纯的功能丰富要重要得多。
1.2 为什么 Docker 部署是首选方案
Honey 本身是 Python 写的,理论上你可以在宿主机上直接 pip install 依赖然后跑进程。但我强烈不建议这么干,原因有三点。
第一,Python 环境的隔离问题。你的服务器上可能已经有了一堆服务,有的是 Node 写的,有的用的 Python 3.8,有的要 Python 3.11。直接在宿主机上给 Honey 装依赖,很容易出现版本冲突。Docker 把 Python 环境和项目依赖全打包进容器里,宿主机只需要一个 Docker 运行时,干净利落。
第二,升级和回滚的便利性。Honey 这种快速迭代的小项目,作者更新频率并不慢,可能隔一两周就有个小版本。用 Docker 部署的话,升级就是拉一个新镜像再重启容器;不满意还能立刻切回旧镜像。如果你是在裸环境里用 pip install,升级之前还得担心会不会把其他服务搞坏,回滚更是麻烦。
第三,数据目录可以清晰隔离。Honey 的配置、订阅数据、日志都在一个数据目录里,用 Docker 参数把宿主机的目录挂载进容器,后续备份只需要打包这一块目录,不用去满硬盘找文件到底写在了哪里。
所以我这篇文章里所有步骤都会围绕 Docker 展开,这也符合多数自托管场景里“能容器化就容器化”的实践原则。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备:Docker 装好之前先避掉两个坑
说到环境准备,网上大多数教程都会直接贴一条安装命令,好像大家机器上都装好了 Docker 一样。但以我接触过的情况来看,真正在部署时卡住的,往往不是 Honey 本身,而是 Docker 环境没弄干净。这里把最常见的问题提前梳理一下。
2.1 不同系统下的 Docker 安装方式
如果你用的是 Ubuntu 或者 Debian 系 Linux,推荐用官方源安装,而不是直接 apt install docker.io。原因很简单,发行版仓库里的 Docker 版本通常偏旧,可能缺少新版 Compose 插件或者一些修复过的 bug。我的操作是:
bash复制# 卸载可能存在的旧版本
sudo apt remove docker docker-engine docker.io containerd runc
# 安装依赖
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
# 添加 Docker 官方 GPG 密钥和软件源
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装 Docker 引擎和 Compose 插件
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
如果你是在 Windows 上用 Docker Desktop,安装过程本身不算复杂,但有一个老生常谈的坑:安装后启动时会提示虚拟化支持没检测到。这个问题多半不是 Docker 的锅,而是 Windows 的虚拟化功能没打开。去“启用或关闭 Windows 功能”里勾选“虚拟机平台”(Virtual Machine Platform)和“适用于 Linux 的 Windows 子系统”,重启后再试试;有些老机器还要到 BIOS 里把 Intel VT-x 或 AMD-V 开关打开。
2.2 换个镜像源,省下大把等待时间
装好 Docker 之后下一步绝对不要直接去拉镜像,先把镜像源配好。国内网络环境下,直接拉 Docker Hub 的镜像经常慢到怀疑人生,或者直接超时。我的做法是编辑 /etc/docker/daemon.json,把 registry-mirrors 配置成自己常用的国内镜像地址:
json复制{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://dockerproxy.com",
"https://docker.nju.edu.cn"
]
}
配置好之后执行 sudo systemctl restart docker 重启 Docker 服务。这一步能省下的时间不是一点点,尤其是 Honey 这种基础镜像可能有好几百兆的情况下,配好源之后下载速度能明显提升。
注意:网上流传的镜像源地址有很多,质量参差不齐,有些很快就不能用了。如果发现某个地址拉取失败,就换一个。我的原则是并列配置两到三个地址,这样单个源出问题时会自动切换。
2.3 验证 Docker 与 Compose 是否就绪
部署前最好花十秒钟确认环境没问题。执行 docker --version 看核心版本,执行 docker compose version 看 Compose 插件是否可用。如果第二行提示找不到命令,说明你用的是旧版 Docker 或者没装 Compose 插件。别慌,新版 Docker Engine 通常自带 docker compose 子命令,如果你系统里只有 docker-compose 这个独立的旧版二进制,建议还是装一下新版插件,因为 Honey 后续的编排文件用新版语法会更省心。
到这里,环境就算准备好了。
3. 配置拆解:理解 Honey 的设置文件再动手
Honey 吸引我的地方就是配置足够简单,但“简单”不代表可以闭着眼睛乱填。我见过有人把配置写坏之后抱怨项目不行的,其实大多数问题都出在没理解那几个字段的含义上。这一节把配置文件的核心逻辑讲清楚。
3.1 目录结构是怎么组织的
Honey 的项目结构大致是这样:后端代码在 backend 目录下,前端页面在 frontend 目录下,而所有用户可修改的数据都集中在 backend/data 目录里,其中最重要的就是 config.json 这个配置文件。
用 Docker 部署时,我们需要把这个数据目录挂载出来,让宿主机可以直接访问:
bash复制# 创建一个专门的目录存放 Honey 数据
mkdir -p ~/docker/honey/data
后续所有持久化数据都放在这个目录里,即使容器删了重建,配置也不会丢。这一点非常关键,容器是“一次性”的,但数据必须留在外面。
3.2 核心配置项逐项讲清楚
首次启动后,Honey 会自动生成一份默认配置。一般来说我们只需要改少数几个地方,下面我把自己实际使用的配置贴出来,逐步说明每项的作用:
json复制{
"port": 1200,
"host": "0.0.0.0",
"language": "zh-cn",
"units": "metric",
"updateInterval": 30,
"weather": {
"apiKey": "你的 OpenWeatherMap API Key",
"city": "Shenzhen"
},
"rss": [
"https://example.com/feed.xml",
"https://another-feed.com/rss"
],
"system": {
"enabled": true,
"interval": 10
}
}
逐项说一说:
port和host:Honey 服务监听的端口和地址。默认 1200 端口,host设为0.0.0.0表示允许局域网内其他设备访问,如果你只想本机访问,可以改成127.0.0.1。language:界面语言,Honey 支持多种语言,这里设成zh-cn就是中文界面。units:温度单位,metric对应摄氏度,imperial对应华氏度,国内用户一般用 metric。updateInterval:仪表盘数据刷新间隔,单位是秒。我设 30 秒,对天气和 RSS 来说足够实时,又不会频繁请求 API 导致被限流。weather.apiKey:天气数据提供方的 API Key。Honey 默认支持 OpenWeatherMap,你需要去对应平台注册一个免费账号并申请 Key。这里务必注意,免费版 API 有调用频率限制,不要把刷新间隔设得太短。weather.city:城市名称,建议填英文名称,国内市名用拼音基本都能识别。rss:这是一个字符串数组,填你想订阅的 RSS 源地址。注意每个地址都必须带http://或https://前缀,否则解析会失败。system.enabled和system.interval:是否显示宿主机系统信息(CPU、内存、磁盘占用),以及多少秒刷新一次。设成true和10表示每 10 秒刷新一次系统负载数据。
3.3 关于 JSON 格式的三个提醒
配置文件是一个 JSON 文件,格式稍有不对整个服务就会读取失败。这里分享三个我在实际使用中踩过的具体问题:
第一,JSON 文件里不允许有注释。很多初次接触的人喜欢在配置里加 // 这是端口 这类注释,这在某些配置文件里可以,但在 JSON 里是语法错误。如果你需要做标注,建议单独在旁边建一个说明文档,或者在修改前先把原始文件备份一份。
第二,最后一个键值对后面不要跟逗号。这是极高频的低级错误,比如 "port": 1200, 如果后面没有其他项了,这个逗号就会导致解析失败。
第三,修改配置后要重启容器才能生效。Honey 不会热加载配置文件,改完配置必须执行 docker restart 或者用 Compose 重启服务。
4. 部署实操:两条路线完整跑通
配置逻辑清楚之后,部署就是水到渠成的事了。这一节提供两种方式,一种适合快速验证,一种适合正式使用。我建议第一次接触的人先用第一种跑通流程,确认没问题再切换成第二种。
4.1 方式一:docker run 一行命令快速启动
如果你只是先试试 Honey 的效果,不想引入额外文件,直接用 docker run 就够了。我的启动命令是这样:
bash复制docker run -d \
--name honey \
-p 1200:1200 \
-v ~/docker/honey/data:/app/backend/data \
--restart unless-stopped \
hween/honey:latest
简单解释一下各个参数的作用:
-d:后台运行容器。--name honey:给容器起一个固定名字,方便后续用docker logs honey查看日志、用docker restart honey重启。-p 1200:1200:将宿主机 1200 端口映射到容器内 1200 端口。如果你宿主机上 1200 端口已经被占了,可以改成宿主机的其他端口,比如-p 8080:1200。-v ~/docker/honey/data:/app/backend/data:挂载数据目录。把刚才创建的宿主机目录映射到容器内的数据目录,这样配置和订阅数据都存在宿主机上。--restart unless-stopped:设置容器在 Docker 服务启动时自动重启,除非手动停止。这个参数建议加上,否则服务器重启后容器不会自动起来。hween/honey:latest:镜像名和标签。如果你所在环境拉取不到 latest,可以尝试指定一个具体的版本号。
启动后执行 docker ps 看容器状态,状态是 Up 就说明没问题了。然后浏览器访问 http://你的服务器IP:1200,应该能看到 Honey 的默认页面。
4.2 方式二:docker-compose 编排,正式使用更顺手
如果觉得 docker run 命令太长不好记,或者你还有其他服务要一起管理,我更推荐用 Compose 方式。创建一个 docker-compose.yml 文件,内容如下:
yaml复制services:
honey:
image: hween/honey:latest
container_name: honey
restart: unless-stopped
ports:
- "1200:1200"
volumes:
- ./data:/app/backend/data
environment:
- TZ=Asia/Shanghai
比起 docker run,Compose 文件有两个额外好处。一个是时区设置,通过 TZ=Asia/Shanghai 环境变量让容器内的时区跟本地一致,否则时间显示会差 8 个小时。另一个是目录管理,./data 会以 Compose 文件所在的目录为基准自动创建,整个部署目录看起来就是一套完整配置,删掉也方便。
启动命令:
bash复制docker compose up -d
第一次执行会自动拉取镜像然后启动容器。之后就算容器崩了或者服务器重启了,只要执行 docker compose down && docker compose up -d 就能干净地重建。
4.3 浏览器访问与首屏数据检查
启动完成后,浏览器访问对应地址。第一次打开看到的可能是空白或者提示数据加载中,这时候先别急,去确认两件事。
第一,用 docker logs honey 查看容器日志,确认没有报错。正常情况下日志里会有访问记录或者后端服务启动成功的提示。如果看到异常堆栈,多半是配置文件格式有问题或者 API Key 无效。
第二,打开前端页面之后,用浏览器的开发者工具(F12)切到 Network 面板,刷新页面,看看请求后端 API 的返回状态是不是 200。如果某些数据块显示不出来,点开对应的 API 请求看返回内容,错误信息会直接告诉你是天气 Key 无效还是 RSS 地址解析失败。
初次启动页面没有数据是正常的,因为需要等第一个刷新周期拉取数据。我的习惯是把 updateInterval 临时设成一个很小的值,比如 5 秒,确认数据能正常拉到之后再改回 30 秒。
4.4 让 Honey 跑得更省心的两个细节
一是端口的选择。1200 是 Honey 默认端口,但如果你家里还有别的服务,比如 NAS 的管理界面或者某个 Web 应用,很可能已经把 1200 占了。我的建议是统一规划好端口段,比如所有自托管服务都分布在 1000~2000 之间,避免冲突。
二是数据备份。由于 Honey 的数据全在数据目录里,备份就变得很简单。我写了一个简单的定时任务,每天把 ~/docker/honey/data 打包压缩,然后同步到家里的备份盘上。对于配置文件和 RSS 订阅这种小量数据,整个备份过程不到一分钟。
5. 常见问题与排查技巧实录
不管脚本写得多顺,实际部署时总会遇到一些幺蛾子。这里把我自己遇到的问题和帮朋友排查过的典型故障列成一张速查表,方便你对照解决。
5.1 典型问题速查表
| 现象 | 可能原因 | 解决方法 |
|---|---|---|
| 容器启动后马上退出 | 配置文件 JSON 格式错误,或者端口被占用 | 修改 config.json,用 JSON 验证工具检查语法;换一个宿主机端口映射 |
| 页面能打开但天气不显示 | API Key 无效、城市名无法识别、刷新间隔太短触发限流 | 检查 weather 配置,确认 Key 有效;城市名改用英文拼音;适当调大 updateInterval |
| RSS 列表加载失败 | 地址不带协议头、源本身不可访问、源返回非标准格式 | 确认每个地址都有 http/https 前缀;用 curl 测试源地址是否能正常返回 XML |
| 系统信息显示 0 或者不更新 | system.enabled 未开启,或容器内没有读取宿主机信息权限 | 确认配置中 system.enabled 为 true;检查 interval 是否太短导致数据来不及刷新 |
| 时间显示比本地时间差 8 小时 | 容器时区没有设置 | 在 Compose 文件或 docker run 中添加 TZ=Asia/Shanghai 环境变量后重启容器 |
| 局域网内其他设备无法访问 | host 配置为 127.0.0.1,或宿主机防火墙没放行端口 | 确认 host 为 0.0.0.0;检查防火墙规则,放行 1200 端口 |
| 拉取镜像慢或超时 | 网络原因导致 Docker Hub 访问不稳定 | 配置 registry-mirrors 镜像加速;或更换网络环境再试 |
5.2 一个屡试不爽的排查思路
很多人遇到容器起不来就慌,直接删了重建,但这样往往丢掉了关键线索。我的做法是:先看日志。
bash复制docker logs honey --tail 50
这个命令可以查看最近 50 行日志。Honey 启动失败时,日志里通常会写明是端口绑定失败、配置文件解析失败,还是某个依赖服务连不上。拿到具体报错信息再去搜索,比盲猜要高效得多。
如果日志显示配置文件解析失败,但我又看不出 JSON 哪里有问题,我的办法是找到一个在线 JSON 校验工具,把 config.json 的内容贴进去,它会把错误位置精确指出来。这种方法十次有九次能直接定位到问题行。
5.3 我实际踩过的一个难忘的坑
在给一台 Ubuntu 服务器部署时,我遇到了一个非常奇怪的现象:docker ps 显示容器是 Up 状态,但浏览器访问就是不出页面。第一次排查,我以为端口映射出了问题,反复确认也没发现异常;后来偶然看了一下容器日志,发现里面有 Address already in use 的报错,但容器却没有立刻退出。
深入查了之后才发现,是 Honey 容器在启动监听端口时出了问题,但主进程没有退出,所以 Docker 认为它还在运行。这种情况的解决办法就是把宿主机上占用该端口的进程找出来:
bash复制sudo lsof -i :1200
查到占用进程后,要么换 Honey 的端口,要么处理掉冲突进程。这个经历提醒我,容器状态是 Up 并不代表服务就一定健康,遇到访问不了时,日志永远是第一现场。
5.4 另一个容易忽略的问题:重启后的数据丢失
有一种情况非常阴险:容器没写挂载卷,但数据看起来一直是正常的,直到某天你执行了 docker compose down 再 up,发现之前配置好的 RSS 源和页面设置全部恢复出厂。原因就是你忘了挂载数据目录。
这种问题在刚开始部署时几乎不会被注意,因为容器还在运行,数据确实写进了容器内部,直到容器重建才会暴露。所以每次部署完成后,我都习惯执行一下 docker inspect honey,在输出里确认 Mounts 部分确实包含了宿主机数据目录的挂载信息。这一步看起来多余,但能帮你躲掉一个大坑。
我个人在实际操作中的体会是,Honey 这类轻量仪表盘,真正难的不是部署,而是搞清楚它适合解决什么问题,以及怎么把它嵌入到你已有的服务矩阵里。如果你只是需要一个“一打开浏览器就能看到关键信息”的页面,它比那些重型监控平台省心太多。最后再分享一个小技巧:你完全可以把 Honey 的地址设置成浏览器新标签页的默认页面,配合 --restart unless-stopped 和自动备份,这个仪表盘基本就不用再管它了,安安静静地每天都在那儿等着你。
