[{"data":1,"prerenderedAt":270},["ShallowReactive",2],{"content:\u002Fposts\u002Fups-monitoring-trilogy-nodejs":3,"surround:\u002Fposts\u002Fups-monitoring-trilogy-nodejs":259},{"id":4,"title":5,"body":6,"categories":232,"date":234,"description":235,"draft":236,"extension":237,"image":238,"meta":239,"navigation":241,"path":242,"permalink":238,"pinned":236,"published":238,"readingTime":243,"recommend":238,"references":238,"seo":248,"sitemap":249,"stem":250,"tags":251,"type":257,"updated":234,"__hash__":258},"content\u002Fposts\u002Fposts\u002Fups-monitoring-trilogy-nodejs.md","为了护住我那几块硬盘：我的 UPS 监控“三部曲",{"type":7,"value":8,"toc":216},"minimark",[9,19,22,25,30,35,38,46,57,67,71,74,81,89,93,99,109,117,121,124,128,131,141,145,148,154,158,164,197,201,204,207],[10,11,15],"alert",{"type":12,"icon":13,"title":14},"info","tabler:robot","AI 迁移提示",[16,17,18],"p",{},"本文由 AI 协助从旧站迁移，尚未完成逐篇人工审校；内容如有疏漏，将在复核后修订。",[16,20,21],{},"搞 HomeLab 的人，最后都会殊途同归地买台 UPS。毕竟看着那几块存满了“学习资料”的硬盘，谁也不想在停电时赌一把运气。",[16,23,24],{},"但 UPS 买回来后，怎么看状态就成了个问题。为了能随时随地盯一眼电量，我前前后后折腾了三个版本。",[26,27,29],"h2",{"id":28},"️-从能看到优雅三个版本的演进","🛠️ 从“能看”到“优雅”：三个版本的演进",[31,32,34],"h3",{"id":33},"v10pve-备注栏的暴力补丁","v1.0：PVE 备注栏的“暴力补丁”",[16,36,37],{},"最开始的想法特别简单直接：既然我天天盯着 PVE 后台，那把 UPS 信息塞进 PVE 不就行了？",[16,39,40,41,45],{},"于是我写了个 Python 脚本，定时抓取 ",[42,43,44],"code",{"code":44},"upsc"," 的数据，然后通过 PVE 的 API 强行写进节点的“备注”里。",[47,48,49],"ul",{},[50,51,52,56],"li",{},[53,54,55],"strong",{},"现状","：能看，但丑。备注栏那一堆乱糟糟的字符，每次看都觉得自己像个原始人。",[58,59,60],"blockquote",{},[16,61,62],{},[63,64],"img",{"alt":65,"src":66},"v1 版本 PVE 节点备注展示截图",".\u002Fimages\u002Fups-v1-pve-note.webp",[31,68,70],{"id":69},"v20魔改-pve-的状态面板","v2.0：魔改 PVE 的状态面板",[16,72,73],{},"后来不满足于备注栏，我开始打 PVE 源码的主意。通过修改 PVE 的 ExtJS 文件，我强行在宿主机的状态监控页里插了一个 UPS 的展示位。",[47,75,76],{},[50,77,78,80],{},[53,79,55],{},"：看着很高级，和系统融为一体。但有个致命伤：只要 PVE 一更新，改动就全没了，得重新修代码，简直是体力活。",[58,82,83],{},[16,84,85],{},[63,86],{"alt":87,"src":88},"v2 版本魔改 PVE 状态页截图",".\u002Fimages\u002Fups-v2-pve-ui.webp",[31,90,92],{"id":91},"v30独立-web-版ups-web","v3.0：独立 Web 版（UPS Web）",[16,94,95,96],{},"也就是这次要分享的终极方案：",[53,97,98],{},"不依赖宿主机系统，做一个彻底独立的监控页。",[16,100,101,102,105,106,108],{},"这一次我用 Node.js 重新写了一套逻辑，最核心的一点是：",[53,103,104],{},"我用纯 JS 实现了 NUT（Network UPS Tools）客户端协议。"," 这意味着它不再需要你安装任何 ",[42,107,44],{"code":44}," 命令，只要能跑 Node 或 Docker 的地方，它就能直接和你的 UPS 服务器对话。",[58,110,111],{},[16,112,113],{},[63,114],{"alt":115,"src":116},"v3 版本独立 Web 监控页截图",".\u002Fimages\u002Fups-v3-pve-ui.webp",[26,118,120],{"id":119},"部署指南","📦 部署指南",[16,122,123],{},"为了方便复刻，我将 v3.0 整理成了标准项目。推荐使用 Docker 部署，以保持环境整洁。",[31,125,127],{"id":126},"方法一使用-docker推荐","方法一：使用 Docker（推荐）",[16,129,130],{},"为了确保你在网页上修改的配置不会因为容器重启而丢失，请务必挂载配置文件：",[132,133,139],"pre",{"className":134,"code":136,"language":137,"meta":138},[135],"language-bash","# 创建配置存储文件\ntouch config.json\n\n# 运行容器\ndocker run -d \\\n  --name ups-web \\\n  -p 8765:8765 \\\n  -v $(pwd)\u002Fconfig.json:\u002Fapp\u002Fconfig.json \\\n  -e HOST=0.0.0.0 \\\n  -e PORT=8765 \\\n  --restart always \\\n  ups-web\n","bash","",[42,140,136],{"__ignoreMap":138},[31,142,144],{"id":143},"方法二源码运行","方法二：源码运行",[16,146,147],{},"如果你想直接在 Node.js 环境下跑：",[132,149,152],{"className":150,"code":151,"language":137,"meta":138},[135],"git clone https:\u002F\u002Fgithub.com\u002Folinll\u002Fnut-guard.git\ncd nut-guard\nnpm install\nnpm start\n",[42,153,151],{"__ignoreMap":138},[26,155,157],{"id":156},"️-安全与避坑提醒","⚠️ 安全与避坑提醒",[10,159,161],{"type":160},"warning",[16,162,163],{},"该项目暂未内置登录鉴权，暴露到公网存在安全风险。建议配合 Nginx Access List 限制访问，或仅在局域网内使用。",[165,166,167,177,191],"ol",{},[50,168,169,172,173,176],{},[53,170,171],{},"权限控制","：该项目暂未内置登录鉴权，建议配合 ",[53,174,175],{},"Nginx Proxy Manager"," 加上 Access List，或者仅在局域网内使用。",[50,178,179,182,183,186,187,190],{},[53,180,181],{},"配置冲突","：通过 URL 参数 ",[42,184,185],{"code":185},"?ip=10.0.0.1"," 临时查看时，不会改写 ",[42,188,189],{"code":189},"config.json","。",[50,192,193,196],{},[53,194,195],{},"持久化","：如果是在 PVE 容器（LXC）里跑，记得开启相应的网络权限。",[26,198,200],{"id":199},"结语","🎬 结语",[16,202,203],{},"从最开始在备注栏抠字，到如今拥有一个独立的监控大屏，这不仅是为了护住那几块硬盘，更是折腾 HomeLab 的乐趣所在。",[16,205,206],{},"目前项目已在 GitHub 开源：",[16,208,209],{},[210,211,215],"a",{"href":212,"rel":213},"https:\u002F\u002Fgithub.com\u002Folinll\u002Fnut-guard",[214],"nofollow","olinll\u002Fnut-guard",{"title":138,"searchDepth":217,"depth":217,"links":218},4,[219,226,230,231],{"id":28,"depth":220,"text":29,"children":221},2,[222,224,225],{"id":33,"depth":223,"text":34},3,{"id":69,"depth":223,"text":70},{"id":91,"depth":223,"text":92},{"id":119,"depth":220,"text":120,"children":227},[228,229],{"id":126,"depth":223,"text":127},{"id":143,"depth":223,"text":144},{"id":156,"depth":220,"text":157},{"id":199,"depth":220,"text":200},[233],"服务","2026-04-01","从 PVE 备注里的简陋脚本，到独立的 Node.js Web 监控页，记录一个 HomeLab 玩家的 UPS 监控进阶之路。",false,"md",null,{"slots":240},{},true,"\u002Fposts\u002Fups-monitoring-trilogy-nodejs",{"text":244,"minutes":245,"time":246,"words":247},"5 min read",4.01,240600,802,{"title":5,"description":235},{"loc":242},"posts\u002Fposts\u002Fups-monitoring-trilogy-nodejs",[252,253,254,255,256],"UPS","HomeLab","Node.js","PVE","NUT","tech","TkXsG93lFjHGj-vtoCkZvv5JiUgGEgioqWTF-18J2eY",[260,265],{"title":261,"path":262,"stem":263,"date":264,"type":257,"children":-1},"CI\u002FCD 手册：Jenkins 自动化发布全流程","\u002Fposts\u002Fjenkins-deploy-nodejs-springboot","posts\u002Fposts\u002Fjenkins-deploy-nodejs-springboot","2026-03-30",{"title":266,"path":267,"stem":268,"date":269,"type":257,"children":-1},"Nginx 使用 sub_filter 注入自定义 HTML 标签","\u002Fposts\u002Fnginx-subfilter-html","posts\u002Fposts\u002Fnginx-subfilter-html","2026-04-11 00:00:00",1788712222945]