Skip to content

feat(deploy): 部署编排重写 — 加速镜像默认 / 健康检查 / 下载加速(已实测) - #112

Open
suantea wants to merge 1 commit into
PIKACHUIM:mainfrom
suantea:feat/deploy-compose
Open

suantea wants to merge 1 commit into
PIKACHUIM:mainfrom
suantea:feat/deploy-compose

Conversation

@suantea

@suantea suantea commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator

拉取实测结果(按要求提前测试)

途径 结果
ghcr.io/pikachuim/netpanel:latest 直连 ❌ 卡死(blob CDN 不可达,2 分钟无进度)
ghcr.m.daocloud.io/... ❌ 403 Forbidden
ghcr.nju.edu.cn/...(南京大学镜像) ✅ 整镜像 8 秒拉完

镜像端到端验证:拉取 → docker run → 6 秒内 /api/v1/init/status 返回 200 → docker compose up/down 全链路通过(多架构 amd64/arm64 镜像,arm64 本机实测)。

顺带发现并修复:compose 镜像名是错的

原 compose 引用 ghcr.io/netpanel/netpanel:latest,而 CI 实际发布的是 ghcr.io/pikachuim/netpanel——按原 compose 部署必然失败。

改动

docker-compose.yml(重写)

  • 默认镜像走实测可用的 ghcr.nju.edu.cn 加速源;NETPANEL_IMAGE 可一键切回官方源(海外环境)
  • NETPANEL_PORT 端口可调;显式文档化 NETPANEL_METRICS_TOKEN / NETPANEL_MCP_TOKEN / NETPANEL_GH_MIRROR 全部环境变量
  • 容器日志轮转(json-file 10m × 3)防无界增长

Dockerfile

  • 内置 HEALTHCHECK:探活公开端点 /api/v1/init/status(30s 间隔 / 20s 启动宽限),下一次镜像构建起 docker ps 显示 healthy

面板内下载加速(backend/service/cftunnel)

  • 新增 NETPANEL_GH_MIRROR 环境变量:配置后面板下载 cloudflared 二进制走 GitHub 加速镜像(如 https://ghfast.top)。国内部署首次启动卡在下载这一步的问题有了配置化解法;留空行为完全不变

兼容性

  • compose 变量均有默认值,docker compose up -d 零配置可用
  • NETPANEL_GH_MIRROR 不设置时下载行为与现状一致

🤖 Generated with ZCode

@pikachuren pikachuren left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏 感谢 @suantea 提交!
🤖 AI 自动审核声明:本评审报告由 AI 自动生成,当前使用 DeepSeek-V4.1-Flash 模型进行分析。
⚠️ AI 分析结果仅供参考,可能存在误判或遗漏。如您发现任何问题或有不同意见,欢迎随时提出讨论和纠正。
⚠️ 重要提醒:即使 AI 评审认为代码质量良好且建议合并,最终是否合并仍需由项目维护者进行人工判定。项目维护者会综合考虑代码质量、项目规划、技术方向、团队资源等多方面因素做出是否合并的决策。

评审范围:PR-112.own.diff(该 PR 自身增量,4 文件 / +58 −6),base = dc2877b(origin/main),head = 1248b42。
行号以自身改动后的新文件行号(+ 侧)为准。核对方式:git show refs/remotes/pr/112:<path> 与 origin/main 对比。

📖 PR #112 — feat(deploy): 部署编排重写 — 加速镜像默认 / 健康检查 / 下载加速(已实测)

🎯 结论

结论:🔄 Request Changes(修 typo / HEALTHCHECK / 日志轮转值得合并;建议先把"默认第三方镜像源 + 浮动 tag"改为 opt-in 或补 digest 校验)

评分:功能 ⭐⭐⭐⭐ | 最小改动 ⭐⭐⭐ | 前向兼容 ⭐⭐⭐ | 方案设计 ⭐⭐⭐

变更:4 文件(+58 / −6)

整体方案:四个各自独立的小改动:① compose 重写(镜像源参数化、环境变量文档化、端口参数化、日志轮转);② Dockerfile 增加 HEALTHCHECK;③ cftunnel 下载器支持 GitHub 加速前缀;④ .gitignore 忽略 data/。方向正确——其中"compose 里的镜像名与实际发布名不一致"确实是个会让新用户第一步就失败的隐藏问题;但把第三方加速源设为默认值、同时继续使用浮动的 latest tag,等于把"能不能拉到可信任镜像"的信任假设默认交给了第三方站点,这一点建议再收一收。

核心改动清单

  1. docker-compose.yml:22 — 镜像由 ghcr.io/netpanel/netpanel:latest 改为 ${NETPANEL_IMAGE:-ghcr.nju.edu.cn/pikachuim/netpanel:latest}。镜像名修复属实:.github/workflows/docker.yml 用 IMAGE_NAME: ${{ github.repository }},在上游仓库即 ghcr.io/pikachuim/netpanel,原 compose 的 netpanel/netpanel 与之不符。
  2. docker-compose.yml:29-37 — 显式列出 NETPANEL_GH_MIRROR / NETPANEL_METRICS_TOKEN / NETPANEL_MCP_TOKEN,TZ/端口参数化。
  3. docker-compose.yml:47-51 — logging.options.max-size 10m / max-file 3,解决容器日志无界增长(与 main 的 Q1/Q2 类债务呼应,属顺带收益)。
  4. Dockerfile:102-103 — HEALTHCHECK 探活 /api/v1/init/status。不依赖 #117 的 /system/health:该路由在 main 已存在(backend/api/router.go:79 公开注册,backend/api/handlers/init.go:49-52 始终返回 200),因此单独合并不会因端点缺失而把容器标为 unhealthy。alpine:3.19 的 busybox 自带 wget,且 HEALTHCHECK ... CMD <command> 是 shell form,>/dev/null 2>&1 可正常工作。
  5. backend/service/cftunnel/downloader.go:25-34,79 — applyGHProxy 为 GitHub 下载地址拼前缀;未设置环境变量时 applyGHProxy 原样返回,默认行为不变(这一点做得对)。
  6. .gitignore:92 — 新增 data/。

问题清单

  • [P0] docker-compose.yml:22 — 默认镜像源指向第三方 ghcr 代理(ghcr.nju.edu.cn),且 tag 仍是浮动 latest,没有版本号/digest 约束。三点叠加后风险不小:(a)compose 容器默认以 root 运行、带 NET_ADMIN+SYS_MODULE 与 /dev/net/tun(docker-compose.yml:38-43),第三方源返回的任意镜像等价于获得宿主机网络控制面;(b)用户执行第 92 行注释推荐的 docker compose pull && docker compose up -d 时,会在不知情的情况下把既有部署从官方源切到第三方源——"海外服务器建议改用官方源"只是文件顶部注释,实践中很少有人读;(c)代理缓存可能滞后,用户以为升级到了最新版。建议改为"官方源默认、加速源 opt-in",并把 digest 固定作为推荐用法:

    # 默认官方源;国内可显式覆盖为加速源
    image: ${NETPANEL_IMAGE:-ghcr.io/pikachuim/netpanel:latest}
    # 需要可复现/可校验时固定 digest:
    # image: ghcr.io/pikachuim/netpanel@sha256:<digest>

    若维护者确实希望默认加速(考虑国内用户占比),是否可以在 release notes / README 中同步发布每个 tag 的 digest,让用户能自行比对?并明确写一句"默认镜像来自第三方缓存,面板未做内容校验"。

  • [P1] docker-compose.yml:34-35 — 文档化的 NETPANEL_METRICS_TOKEN 在后端并不存在:核对 main 全部 os.Getenv("NETPANEL_*") 只有 NETPANEL_DEBUG / NETPANEL_MCP_TOKEN(pkg/config/config.go:33)/ NETPANEL_ALLOWED_ORIGINS(api/middleware/auth.go:134)/ NETPANEL_ENABLE_SHELL_TASK / NETPANEL_SSH_STRICT_HOST_KEY;也没有 /metrics 路由,且 #113–#121 任一 PR 都未引入该变量。注释"不配置则该端点匿名可读,建议配置"会让运维误以为配置后已鉴权。建议先删掉该行(等真正实现 metrics 鉴权的 PR 再一并加入);顺带把真实存在的 NETPANEL_ALLOWED_ORIGINS(CORS 白名单,见 middleware/auth.go:152-165)补上——它才是影响安全边界的那个变量。

  • [P1] backend/service/cftunnel/downloader.go:25-34,79(配合 DownloadBinary)— 加速只是拼接 URL 前缀,下载产物没有任何校验:DownloadBinary 没有 sha256/GPG 校验,直接 chmod 0755 后由面板(root)执行 cloudflared。一旦按注释配置 NETPANEL_GH_MIRROR=https://ghfast.top,该第三方站点返回的任何二进制都会被落盘执行。cloudflaredVersion 已固定为 2024.8.2(很好),建议在此基础上把预期 sha256 内置或从官方 releases 校验文件获取后校验,并在 UI/文档提示镜像源为第三方。

  • [P1] 镜像名的修复未同步到其它引用点:docsite/guide/installation.md:144、:154 仍写 ghcr.io/netpanel/netpanel:latest(用户照文档装仍会失败);Dockerfile:71 的 org.opencontainers.image.source 也仍是 github.com/netpanel/netpanel。另外 #98(feat/docker-compose-profiles)与 #112 改的是同一个 docker-compose.yml,它新增的 docker-compose.full.yml/docker-compose.minimal.yml 第 11 行同样复制了旧镜像名,并也修改了 docsite/guide/installation.md。是否考虑与 #98 协调合并顺序,或用一次提交把这 5 处引用一起改掉?否则"镜像名错误"会以另一种形式留在仓库里。

  • [P2] Dockerfile:102-103 — 健康检查可用,但期待值建议写清楚:它是纯 HTTP 探活(/api/v1/init/status 在 DB 查询失败时也会返回 200,见 handlers/init.go:31-45 的"保守视为已初始化",所以探不到 DB/端口异常);端口硬编码 8080,若用户用 command: 覆盖 --port 会永久 unhealthy;并且 restart: unless-stopped 在非 swarm 下不会因 unhealthy 重启容器。建议在 compose 注释里点明其局限,避免运维误判。

  • [P2] .gitignore:92 — data/ 会匹配任意层级的 data/ 目录。当前仓库没有被跟踪的 data 目录(已核对 git ls-tree),但将来若某模块新增 xxx/data/(内置资源/样例配置)会被静默忽略。想确认是否改为 /data/(仅根目录)更贴合 compose 的 ./data:/app/data 语义?语义上它与数据卷是一致的 ✓。

  • [P2] 标题里的"(已实测)"在仓库内没有可复核的证据(无 CONTRIBUTORS 记录、无 CI/脚本留痕),仅有 PR body 的一张测算表。其中"原 compose 镜像名是错的"这一条我已独立核实为真;拉取耗时/多架构验证是否可以在 PR 里贴一下 docker image inspect 的 RepoDigests 与拉取日志?这样"已实测"和 digest 校验都能被维护者复核。

  • [P2] 环境变量命名与 #99(feat/scripts: mirror acceleration,NETPANEL_MIRROR)语义相近但名字不同(本 PR 为 NETPANEL_GH_MIRROR)。本地无 pr/99 ref,无法读其 diff(仅依据 PR 标题判断)。若两者都会合入,是否考虑统一前缀/命名,或至少在各处注释中写明"仅作用于面板内下载"与"仅作用于安装脚本"的区别?

产品视角评估:国内用户拉 ghcr 卡住是真实痛点,修镜像名更是必要——这两点的判断都对,日志轮转也是运维会感谢的顺带收益。但从产品取舍看,"默认值"应当是最保守、最可验证的选项,加速属于"知道自己在做什么的用户才需要"的能力,因此更稳妥的做法是默认官方源 + 一行注释/文档给出加速方案,并配合 digest 供比对;这样既解决痛点,又不把信任假设默认转移给第三方。另外,compose 顶部这段注释目前承担了部署文档的角色,建议把其中"升级路径/如何校验镜像"的内容同步进 docsite 或 README,否则 docker compose pull 的用户不会看到。

兼容性/迁移风险:有(仅一项,但性质重要)。

  • 数据卷 ./data:/app/data(docker-compose.yml:27-28)未变,因此不存在"挂载点改变 → 新空库/看起来数据丢失"的问题 ✓;restart / cap_add / devices / sysctls 未变,端口仍只发布 8080(未新增公网暴露端口),未引入 depends_on,也未加资源限制(与 main 一致,非本 PR 引入)。
  • 唯一真正的默认行为变化是镜像来源。建议在 README/compose 顶部补一段"升级说明":默认源变更、如何一键切回官方源、如何校验 digest。
  • .gitignore 新增 data/ 与数据卷语义一致,无需迁移。

值得肯定的点

  1. 抓到并修掉了 compose 镜像名与实际发布名不一致的问题(IMAGE_NAME: ${{ github.repository }}),这是会让新用户第一步就踩空的隐藏坑,且 PR body 给了解释。
  2. HEALTHCHECK 选点恰当:挑了公开且始终 200 的 /api/v1/init/status,没有引入对未合并 PR 的依赖,并正确使用 shell form 以支持输出重定向。
  3. 日志轮转(10m×3)+ 端口参数化 + 把可配置环境变量显式列在 compose 里,是从运维视角出发的实用改进。

建议操作理由:修镜像名、HEALTHCHECK、日志轮转可直接受益,建议保留;但"默认第三方镜像源 + 浮动 tag"建议先改成 opt-in(或补 digest 校验与说明)再合并,并顺手补齐文档中的镜像名引用。

@pikachuren pikachuren left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏 感谢 @suantea 提交!
🤖 AI 自动审核声明。⚠️ 最终合并决策由项目维护者判定。

🎯 结论

✅ Approve with comments(建议跟进 checksum 校验)

📖 概要

部署编排重写 · 加速镜像默认 / 健康检查 / 下载加速
核心改动:docker-compose + Dockerfile 重写,默认镜像源改为南京大学 ghcr 加速站,新增容器 HEALTHCHECK,cloudflared 下载支持 NETPANEL_GH_MIRROR 加速

🚨 关键问题

P1(建议后续跟进):

  • 💡 backend/service/cftunnel/downloader.go 下载 cloudflared 二进制后无 SHA256 checksum 校验即直接执行,若镜像站被劫持或用户配置了恶意镜像 URL,下载到的 binary 会被直接运行(cloudflared 通常以高权限运行网络隧道),存在供应链攻击面。Cloudflare 官方 release 页面有提供 checksum,建议补充固定版本的 SHA256 校验后再落盘执行。

亮点:修复了 docker-compose 里镜像名拼写错误(ghcr.io/netpanel/netpanel → ghcr.io/pikachuim/netpanel),旧文件按原样部署必然失败,这是本 PR 最有价值的修复。

🎯 结论:✅ Approve — 功能价值高,建议后续 PR 补充 cloudflared 下载 checksum 校验

- docker-compose{,.minimal,.full}.yml:镜像/端口支持环境变量覆盖,默认走
  实测可用的 ghcr.nju.edu.cn 加速镜像;显式文档化全部环境变量;日志轮转
  (json-file 10m×3)防容器日志无界增长。上游已将编排拆为默认/精简/完整
  三个变体,故同步应用到三份文件。
- Dockerfile:内置 HEALTHCHECK(探活 /api/v1/init/status),镜像构建后
  docker ps 可见 healthy 状态。
- cftunnel/downloader.go:新增 NETPANEL_GH_MIRROR 环境变量,配置后面板内
  下载 cloudflared 走加速镜像(国内直连 GitHub Releases 常年卡死);留空
  行为不变。
- .gitignore:忽略 docker compose 挂载的 data 数据目录。
@suantea
suantea force-pushed the feat/deploy-compose branch from 1248b42 to 28fa1d2 Compare September 30, 2026 08:42

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants