家用服务器状态页想给家人看?Homepage 仪表盘整理服务入口,再用 cpolar 安全开放临时访问

发布时间:2026/7/15 14:57:15
家用服务器状态页想给家人看?Homepage 仪表盘整理服务入口,再用 cpolar 安全开放临时访问 家用服务器状态页想给家人看Homepage 仪表盘整理服务入口再用 cpolar 安全开放临时访问一台旧笔记本或 NUC 刷了 Linux上面跑了 Jellyfin 看电影、Immich 存照片、Navidrome 听歌、Calibre-Web 看书、Gitea 写笔记、FreshRSS 看订阅。服务越来越多家人每次想用某个功能都得来问那个看电影的叫什么来着IP 多少端口多少服务一多入口就散。每个人记几个 IP端口不现实尤其家人不是技术人员。Homepagegethomepage.dev就是干这个的一个轻量 Docker 仪表盘把你所有自托管服务整理成卡片、分组、带图标和运行状态。家庭内网打开浏览器就能看到全部入口。而 cpolar 解决的场景是——家人出门在外或者过年回老家想看一眼家里的相册或读一本书怎么安全访问用 cpolar 开一个短时 HTTPS 地址只暴露 Homepage 导航页不暴露每个服务的管理端口和后端数据库。本文完整跑通 Homepage 仪表盘 cpolar 临时开放入口从部署、配置到安全边界一步到位。适用场景这套组合适用的具体场景内网跑了 5 个以上 Docker 服务家人记不住每个服务的 IP 和端口号需要一个导航页统一入口。家庭小主机上有照片、音乐、电子书、影视等服务家人出差或旅游时想临时远程看一张照片或听一首歌。不想在路由器上做端口映射不想用 DDNS只想在需要的时候给一段 HTTPS 网址用完后回收。不想把每个服务都暴露到公网只需要暴露一个导航页由家人自己决定点进哪个服务。过年回老家想给父母展示家里 NAS 上存的照片和视频不想折腾 VPN 或路由器配置。核心原则Homepage 只做导航面板不做登录后台cpolar 只暴露导航前台不暴露后端管理端口、Docker Socket、SSH 或数据库。最终效果部署完成后内网得到入口用途是否给家人http://192.168.x.x:3000Homepage 仪表盘展示所有服务卡片和运行状态内网直接访问http://192.168.x.x:3000/adminHomepage 后台配置面板默认关闭需先开启不开放https://xxxx.cpolar.topcpolar 隧道 HTTPS 地址映射到 Homepage 前台只在需要时给家人打开浏览器输入https://xxxx.cpolar.top看到的是一个干净的服务导航页上面有相册卡片点进去是 Immich 界面电影卡片点进去是 Jellyfin 界面音乐卡片点进去是 Navidrome 界面书库卡片点进去是 Calibre-Web 界面RSS 订阅卡片点进去是 FreshRSS 界面每个卡片显示服务在线状态下线时卡片灰色不影响其他卡片使用。环境准备本文以一台 Linux 机器演示。macOS 和 Windows WSL2 的命令基本一致只需把包管理器从 apt 换成 brew / chocolatey。前置条件Linux 机器 / Windows WSL2Ubuntu 22.04、Debian 12 或以上Docker 和 Docker Compose v2.0内网已有至少 2~3 个 Web 服务在运行Jellyfin、Immich、Navidrome 等任选没有也无妨Homepage 空跑一样能展示分组模板已注册 cpolar 账号并拿到 authtokencpolar 官网注册免费套餐够用一个浏览器Chrome / Edge / Firefox 均可确认基础环境正常docker --version docker compose version cpolar version如果还没有 cpolar安装并登录curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bash cpolar authtoken 你的tokencpolar 安装后先确保能正常启动隧道后面会用到。Docker 启动 Homepage 仪表盘创建一个专用目录存放 Homepage 的配置和数据mkdir -p ~/homepage cd ~/homepage新建docker-compose.ymlcat docker-compose.yml EOF services: homepage: image: ghcr.io/gethomepage/homepage:latest container_name: homepage restart: unless-stopped ports: - 3000:3000 volumes: - ./config:/app/config - /var/run/docker.sock:/var/run/docker.sock:ro environment: - PUID1000 - PGID1000 labels: - homepage.groupInfrastructure - homepage.nameHomepage - homepage.iconhomepage - homepage.hrefhttp://localhost:3000 - homepage.descriptionDashboard EOF启动容器docker compose up -d查看日志确认启动正常docker compose logs -f看到Listening on port 3000或类似日志后打开浏览器访问http://localhost:3000。这时候看到的默认页面是一个空白仪表盘因为还没有配 services.yaml。注意挂载/var/run/docker.sock:ro是为了让 Homepage 自动发现本机运行中的 Docker 容器并在卡片上显示在线/下线状态。如果不想给这个权限可以去掉这一行之后手动配置每个服务的 URL。配置服务入口、分组和图标Homepage 的核心配置在~/homepage/config/下。需要创建以下文件文件用途services.yaml服务卡片列表widgets.yaml小组件天气、日期、资源监控等settings.yaml全局配置布局、主题、语言等先创建services.yaml。下面以家庭常见服务为例做分组展示cat config/services.yaml EOF --- # 分组媒体中心 - Media: - Immich: icon: https://cdn.jsdelivr.net/npm/simple-iconsv13/icons/immich.svg href: http://192.168.1.100:2283 description: 家庭照片管理 server: local container: immich-server - Jellyfin: icon: https://cdn.jsdelivr.net/npm/simple-iconsv13/icons/jellyfin.svg href: http://192.168.1.100:8096 description: 电影和电视剧 server: local container: jellyfin - Navidrome: icon: https://cdn.jsdelivr.net/npm/simple-iconsv13/icons/navidrome.svg href: http://192.168.1.100:4533 description: 音乐流媒体 server: local container: navidrome # 分组阅读与内容 - Reading: - Calibre-Web: icon: https://cdn.jsdelivr.net/npm/simple-iconsv13/icons/calibreweb.svg href: http://192.168.1.100:8083 description: 电子书库 server: local container: calibre-web - FreshRSS: icon: https://cdn.jsdelivr.net/npm/simple-iconsv13/icons/freshrss.svg href: http://192.168.1.100:8080 description: RSS 阅读器 server: local container: freshrss # 分组开发与工具 - Utilities: - Gitea: icon: https://cdn.jsdelivr.net/npm/simple-iconsv13/icons/gitea.svg href: http://192.168.1.100:3001 description: Git 仓库 server: local container: gitea - Uptime Kuma: icon: https://cdn.jsdelivr.net/npm/simple-iconsv13/icons/uptimekuma.svg href: http://192.168.1.100:3002 description: 服务监控 server: local container: uptime-kuma EOF再配置widgets.yaml在顶部显示日期、天气和系统资源cat config/widgets.yaml EOF --- - greeting: text_size: xl text: {{HOSTNAME}} 家庭服务 - search: provider: google target: _blank - resources: cpu: true memory: true disk: / cputemp: true uptime: true - datetime: text_size: md format: dateStyle: long timeStyle: short hour12: false - weather: # 替换成你的城市编码openweathermap 免费注册获取 API key # 不配置天气也不会影响其他功能 # city: Beijing # apiKey: your_openweather_api_key EOF配置settings.yamlcat config/settings.yaml EOF --- providers: openweather: # 留空或填 API key apiKey: layout: Media: style: row columns: 3 Reading: style: row columns: 3 Utilities: style: row columns: 3 title: 家庭服务导航 headerStyle: boxed hideVersion: true useEqualHeights: true EOF全部写入后重启 Homepage 使配置生效docker compose restart等 10 秒左右刷新http://localhost:3000应该能看到分组的服务卡片。每个卡片显示图标、名称、描述并标注服务在线状态绿色圆点在线灰色离线。配置技巧如果某个容器的容器名container 字段不匹配状态会一直显示灰色。可以去掉 container 字段只保留 href卡片照常可点击。图标用 simple-icons 的 CDN 链接格式https://cdn.jsdelivr.net/npm/simple-iconsv13/icons/英文名.svg。Homepage 也支持直接用 emoji 或自定义 base64 SVG。分组名可以随意改services.yaml 里- GroupName:就是分组标题行。如果不想显示某个卡片的状态指示灯去掉server和container字段即可。可选让 Homepage 自动发现 Docker 容器前面 docker-compose.yml 挂载了/var/run/docker.sockHomepage 自动扫描本机运行的 Docker 容器。但自动发现的卡片只有标题容器名没有分组、图标和描述。如果要细化还是要手动在 services.yaml 里写。自动发现作为补充在服务页底部列出尚未整理的新容器。如果想用自动发现不必额外配置。重启后如果看到有未分类的卡片说明自动发现生效。可选后台管理面板Homepage 默认不启用 admin 面板。如果需要登录后管理配置编辑config/settings.yaml添加showStats: true然后在 docker-compose.yml 的 environment 里加上认证信息。但本文场景下不开启 admin 面板——家人只需要看导航页不需要看到后台。管理员直接在服务器上用vi编辑config/services.yaml即可。用 cpolar 临时 HTTPS 给家人分享内网 Homepage 跑通后家人出门在外时怎么访问cpolar 在服务器上创建一个隧道把内网的 Homepage 端口映射成公网 HTTPS 地址家人打开浏览器输入这个地址就能看到仪表盘。先启动一个临时隧道只映射 Homepage 的 3000 端口cpolar http 3000成功输出类似Forwarding http://xxxx.cpolar.top - http://localhost:3000 Forwarding https://xxxx.cpolar.top - http://localhost:3000把https://xxxx.cpolar.top发给家人手机或电脑浏览器直接打开就能看到和家里内网一样的仪表盘页面。如果想把隧道放在后台运行不受当前终端影响用 systemd 管理cpolar authtoken 你的token # 编辑 /etc/systemd/system/cpolar.service sudo tee /etc/systemd/system/cpolar.service /dev/null EOF [Unit] Descriptioncpolar tunnel for Homepage Afternetwork.target Wantsnetwork.target [Service] Typesimple ExecStart/usr/local/bin/cpolar http 3000 Restarton-failure RestartSec5 [Install] WantedBymulti-user.target EOF sudo systemctl daemon-reload sudo systemctl start cpolar sudo systemctl enable cpolar # 可选开机自启用 systemd 方式启动后每次只想临时开放时手动执行sudo systemctl start cpolar用完执行sudo systemctl stop cpolar。不需要的时候不要开自启。查看当前隧道分配的地址sudo journalctl -u cpolar -n 20 --no-pager在日志中找到Forwarding https://...那一行那就是家人要用的地址。安全边界用完即关Homepage cpolar 的安全风险主要在导航页暴露了内网哪些服务。以下是每一步的安全操作清单操作一只分配前台端口不暴露后台端口cpolar 只映射 3000 端口Homepage不映射 Jellyfin 的 8096、Immich 的 2283 等。家人通过 Homepage 的导航卡片点击浏览器会走内网地址如果在外网访问会因为地址是内网 IP 而打不开——这是设计意图。家人真正需要的是从 Homepage 上看到有哪些服务可用然后自己选一个通过 cpolar 或路由器端口映射单独开放那个服务的临时入口。如果只给家人看相册单独用另一条 cpolar 隧道暴露 Immich 端口而不是把所有服务全打开。如果一定要在外面也能访问内网服务有两个办法多隧道模式为每个需要外网访问的服务启动独立 cpolar 隧道分别给出不同地址。透传方案Homepage 的 href 写成反向代理路径如http://192.168.1.100:3000/jellyfin且前端反代统一走 3000 端口。本文使用第 1 种——每服务独立隧道用完即关精细控制暴露面。操作二cpolar 隧道用完立即关闭# 如果前台启动CtrlC 直接关闭 # 如果 systemd 启动 sudo systemctl stop cpolar sudo systemctl disable cpolar # 确认隧道已关闭 cpolar status输出应显示无活跃隧道或已断开。操作三不在导航页放置管理链接services.yaml 里不要写 Portainer、SSH Web 终端、Docker Socket 等管理工具的入口。家人用不到管理功能反而会增加暴露风险。操作四避免导航页泄漏内网 IPservices.yaml 中的 href 写内网 IP 没问题家人点击后如果在内网环境正常跳转如果在 cpolar 外网环境点进去会跳转到内网地址导致打不开但这不会泄漏更多信息。如果在意地址泄漏可以把 href 写成模糊名称或不写。操作五定期清理不用的服务卡片家庭服务会增减更替。不用的卡片删除后重启 Homepage保持导航页干净。减少暴露面意味着减少家人点错的风险。# 修改 services.yaml 后 docker compose restart操作六日志检查# 查看 Homepage 访问日志 docker compose logs homepage --tail 50 # 查看 cpolar 连接记录 sudo journalctl -u cpolar -n 30 --no-pager查看是否有异常 IP 多次扫描非正常路径。免费套餐的 cpolar 日志保留有限但足够排查高频访问。常见问题 / 排错Q1启动后访问 localhost:3000 显示白屏原因Homepage 需要先加载配置文件和资源首次启动浏览器页面短暂空白。等 30 秒后刷新。如果持续白屏查看容器日志docker compose logs homepage常见错误配置文件 YAML 缩进错误Homepage 对缩进非常敏感、容器网络不通、无法访问 icon 的 CDN 地址。可以先用无配置模式测试mv config/services.yaml config/services.yaml.bak docker compose restart此时访问localhost:3000应显示空仪表盘。如果空仪表盘正常说明问题在 services.yaml 的格式或内容上。Q2服务卡片一直显示灰色离线排查方向如下container填写的容器名与 Docker 实际容器名不一致。用docker ps查看真实容器名。server写的是local但 Homepage 容器和要检测的服务容器不在同一个 Docker 网络上。如果服务容器没在 homepage 的 docker-compose.yml 的networks里状态检测会失败。如果不是 Docker 容器比如宿主机直接跑的进程去掉server和container字段卡片变为无状态模式。Q3图标不显示检查 services.yaml 中的 icon URL 是否可访问。Homepage 默认从 CDN 或者icons/目录加载图标。以下解决方法确认 simple-icons CDN 地址有没有写错区分大小写如jellyfin不是Jellyfin。换用 emoji 图标icon: emoji-格式是emoji-后接 emoji 字符。把 SVG 文件下载到本地放在config/icons/目录下然后icon: /icons/jellyfin.svg。如果内网访问 CDN 慢可以自建图标反向代理或全部改用 emoji。Q4cpolar 隧道启动后浏览器访问显示 502 Bad Gateway原因cpolar 无法连接内网 3000 端口。检查步骤# 确认 Homepage 容器在运行 docker ps | grep homepage # 确认端口映射正常 curl -I http://localhost:3000 # 从宿主机之外的另一台设备确认 curl -I http://192.168.1.100:3000如果内网访问正常但 cpolar 显示 502检查防火墙是否阻止了回环连接。Q5配置修改后不生效Homepage 不会热加载配置文件的改动。修改 services.yaml / widgets.yaml / settings.yaml 后需要重启docker compose restart如果想使用 Homepage 的 admin 面板在线编辑家庭场景用不到需要在 settings.yaml 里开启enablePasswordProtection: true并配置环境变量。更安全的方式还是在服务器上用 vi 改完重启。Q6cpolar 免费套餐的速率限制cpolar 免费套餐有每月流量和速度限制。如果家人大量浏览照片或串流视频cpolar 隧道会跑满流量后断开。解决方案只通过 cpolar 访问 Homepage 导航页实际照片/视频流量走其他隧道或 VPN。流量到上限后升级套餐或等次月恢复。用完隧道后及时关闭避免后台跑满免费额度。最后Homepage 解决的是服务入口太散的问题cpolar 解决的是临时安全远程访问的问题。两者配合不改变内网服务部署方式不引入 VPN不调路由器只需 Docker 一行启动和 cpolar 一行命令。需要时开隧道用完关隧道管理边界清晰。家人打开手机浏览器就能看到家里的服务导航页——相册、书库、音乐、电影卡片一目了然和在家里操作一样。