Prhub

#26279 fix(docker): generate Cargo.lock in chef stage for sgl-router build

原始 PR 作者 Kangyan-Zhou 合并时间 2026-05-25 16:54 文件变更 1 提交数 2 评论 1 代码增减 +17 / -6

执行摘要

修复 sgl-router Docker 构建缺少 Cargo.lock 的问题

全新检出执行 docker build -f docker/sgl-router.Dockerfile . 失败,因为 Cargo.lock 被 gitignore 导致 COPY 步骤找不到文件。该问题阻塞了新的 nightly-experimental-sgl-router-docker CI 工作流(#26273)的首次运行。

建议精读以了解 Docker 多阶段构建中处理 gitignore 的常见模式。review 中关于 stub 脆弱的评论值得关注,可在后续 PR 中补充警告注释。

讨论亮点

gemini-code-assist[bot] 在评论中指出手动创建 stub 源码文件的方案较脆弱,建议在 experimental/sgl-router/Cargo.toml 中添加警告注释,提示结构变更时需同步更新 Dockerfile。当前评论状态为未解决,但 PR 已合并。

实现拆解

  1. chef 阶段 lockfile 生成:在 docker/sgl-router.Dockerfile 的 chef 阶段,不再从构建上下文复制 Cargo.lock,改为先 stub 最小源码树(src/main.rssrc/lib.rs),然后执行 cargo generate-lockfile 生成锁文件,再运行 cargo chef prepare 导出 recipe。
  2. builder 阶段 lockfile 传播:builder 阶段不再从构建上下文复制 Cargo.lock,改为从 chef 阶段通过 COPY --from=chef /work/Cargo.lock 获取锁文件,确保两个阶段使用相同的依赖解析。
  3. 移除 final build 的 --locked:由于 cargo chef cook 可能修改 Cargo.lock,最终 cargo build 去掉 --locked 标志,避免因 chef 阶段锁文件变异而导致构建失败。
  4. 文档注释更新:Dockerfile 顶部新增注释块,解释 lockfile 生成策略及设计原因,降低未来维护成本。
文件 模块 状态 重要度
docker/sgl-router.Dockerfile 部署脚本 modified 4.11

关键源码片段

docker/sgl-router.Dockerfile infrastructure

唯一的变更文件,实现了完整的 lockfile 生成和传播逻辑,是本次 PR 的核心。

# `Cargo.lock` 被 repo 根 .gitignore 忽略,
# 因此我们在 chef 阶段通过 stub 最小源码树 + cargo generate-lockfile 生成锁文件,
# 然后传播给 builder 阶段,保证两个阶段使用相同的依赖解析,
# 同时不将 5.5k 行的锁文件提交到仓库。FROM rust:${RUST_VERSION}-${DEBIAN_VERSION} AS chef
RUN cargo install cargo-chef --locked --version ^0.1
WORKDIR /work
COPY experimental/sgl-router/Cargo.toml ./
COPY experimental/sgl-router/rust-toolchain.toml ./
​
# 创建最小 stub 源码,使 cargo 能解析 workspace 和生成 lockfile
RUN mkdir -p src && echo "fn main() {}" > src/main.rs \
    && echo "" > src/lib.rs \
    && cargo generate-lockfile \
    && cargo chef prepare --recipe-path recipe.json \
    && rm -rf src
​
FROM rust:${RUST_VERSION}-${DEBIAN_VERSION} AS builder
RUN cargo install cargo-chef --locked --version ^0.1
WORKDIR /work
COPY --from=chef /work/recipe.json ./recipe.json
# 从 chef 阶段复制 lockfile,而非构建上下文
COPY --from=chef /work/Cargo.lock ./Cargo.lock
COPY experimental/sgl-router/rust-toolchain.toml ./
RUN cargo chef cook --release --recipe-path recipe.json
COPY experimental/sgl-router/Cargo.toml ./
COPY experimental/sgl-router/src ./src
# 不使用 --locked:因为 cargo chef cook 可能修改 lockfile,
# 严格 --locked 检查会误报失败
RUN cargo build --release --bin sgl-router \
    && strip target/release/sgl-router

评论区精华

手动创建 stub 源码的脆弱性 设计

gemini-code-assist[bot] 指出手动创建 src/main.rs 和 src/lib.rs 的方案与当前 Cargo.toml 结构紧密耦合,若项目结构变化(如新增 binary 或修改 lib 入口点),Docker 构建会失败。建议在 Cargo.toml 中添加警告注释,提醒开发者同步更新 Dockerfile。

结论:PR 作者未回复直接合并,未添加警告注释,讨论未解决。 · unresolved

风险与影响

低风险。变更仅影响 docker/sgl-router.Dockerfile,不涉及任何运行时逻辑。潜在风险:

  • 如果 Rust 项目结构变化(如新增二进制入口或修改 lib 路径),chef 阶段的 stub 源码可能不再匹配,导致 chef 阶段失败。此风险已被评论提及,但尚未添加警告注释。
  • 移除 --locked 后,若依赖解析在不同构建间产生不一致(例如 registry 更新),可能在 builder 阶段引入意外的依赖版本变更。
  • CI 工作流:修复了 nightly-experimental-sgl-router-docker 工作流的阻塞问题,使其能够正常构建 Docker 镜像。
  • 本地构建:从全新检出可以成功构建 sgl-router Docker 镜像。
  • 维护者:需要了解 Dockerfile 中的 lockfile 生成机制,以防未来项目结构变动时 Dockerfile 失效。
手动 stub 源码与项目结构耦合 移除 --locked 可能导致依赖版本不一致

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论