- 
                Notifications
    
You must be signed in to change notification settings  - Fork 116
 
feat: 优化docker镜像构建逻辑,预计可从原来33分钟提升到十分钟之内 #315
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
          
📝 WalkthroughSummary by CodeRabbit
 Walkthrough更新了容器与CI构建流程:取消忽略 bin/,调整 Dockerfile 以直接拷贝预编译二进制,扩展 Linux 构建平台;重构并升级 GitHub Actions 工作流,替换工具版本、精简矩阵、改写镜像构建/推送与后端编译步骤。 Changes
 Sequence Diagram(s)sequenceDiagram
  autonumber
  participant Dev as Developer
  participant GH as GitHub Actions
  participant Go as Go Build
  participant Bx as Docker Buildx
  participant Reg as Registry
  Dev->>GH: push/tag event
  GH->>GH: Checkout (v5), Setup Node (v5), Setup Go (v6), Cache Go
  GH->>Go: go build with ldflags (GIT_COMMIT/TAG/REPO/BUILD_DATE/VERSION/MODEL/API_*)
  Note over GH,Go: 生成各架构二进制于 bin/
  GH->>Bx: buildx build --platform linux/amd64,linux/arm64<br/>tags=...:${GITHUB_REF_NAME}
  Bx->>Reg: Push multi-arch image
  Reg-->>GH: Image digest
  GH-->>Dev: Job complete
    Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
 Poem
 Pre-merge checks and finishing touches✅ Passed checks (3 passed)
 ✨ Finishing touches🧪 Generate unit tests
 Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs. 
 Please see the documentation for more information. Example: reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment   | 
    
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️  Outside diff range comments (2)
Makefile (1)
54-65: --load 与多平台构建不兼容,docker 目标会失败或降级为单平台docker/podman buildx 在多平台下不支持 --load。当前命令指定了多个 --platform 并使用了 --load,通常会报错或只加载其中一个架构。
建议本地构建改为“当前平台单架构 + --load”,多平台推送交给 CI。示例改动:
- --platform=linux/arm64,linux/amd64,linux/ppc64le,linux/s390x,linux/riscv64 \ - -t weibh/k8m:$(VERSION) -f Dockerfile . --load + -t weibh/k8m:$(VERSION) -f Dockerfile.action . --load如需本地指定单一平台(注意与 --load 同用只能单平台):
- --platform=linux/arm64,linux/amd64,linux/ppc64le,linux/s390x,linux/riscv64 \ + --platform=$(shell $(BUILD_TOOL) info --format '{{.OSType}}/{{.Architecture}}') \.github/workflows/build-release.yml (1)
50-53: 严重:将 OPENAI_API_KEY 烘焙进二进制/发布产物(泄露机密)Make 通过 -ldflags 注入 API_KEY,会把密钥明文写入发布的二进制(公开可下载)。这是高危泄露。
建议在发布构建中完全移除 API_KEY 注入,密钥仅在运行时通过环境变量/外部配置注入:
- make build-all GIT_COMMIT=${{ github.sha }} GIT_TAG=${{ github.ref_name }} GIT_REPOSITORY=${{ github.repository }} BUILD_DATE=${{ env.BUILD_TIME }} VERSION=${{ github.ref_name }} MODEL=${{ env.OPENAI_API_MODEL }} API_KEY=${{ secrets.OPENAI_API_KEY }} API_URL=${{ env.OPENAI_API_URL }} + make build-all GIT_COMMIT=${{ github.sha }} GIT_TAG=${{ github.ref_name }} GIT_REPOSITORY=${{ github.repository }} BUILD_DATE=${{ env.BUILD_TIME }} VERSION=${{ github.ref_name }} MODEL=${{ env.OPENAI_API_MODEL }} API_URL=${{ env.OPENAI_API_URL }}同时在应用运行环境(Kubernetes/容器)通过环境变量传入密钥,代码侧读取而非编译期内嵌。
如需,我可以提交一版:移除 ldflags 的密钥注入,改为从 env 读取并支持缺省兼容。
🧹 Nitpick comments (7)
Dockerfile.action (3)
11-13: 用 COPY 替代 ADD,并一次性赋予执行权限遵循最佳实践与 hadolint(DL3020)建议,且减少后续 chmod。
应用如下修改:
-ADD reload.sh reload.sh -COPY ./bin/${BINARY_NAME}-${TARGETOS}-${TARGETARCH} ${BINARY_NAME} +COPY --chmod=0755 reload.sh /app/reload.sh +COPY --chmod=0755 ./bin/${BINARY_NAME}-${TARGETOS}-${TARGETARCH} /app/${BINARY_NAME}另外请确认构建前已存在 bin/${BINARY_NAME}-${TARGETOS}-${TARGETARCH}(CI 中由 make build-linux 生成)。
14-16: 层缓存与包管理最佳实践:避免 apk upgrade,先装包后拷贝二进制
- apk upgrade 不建议在镜像中执行,容易导致不可重现与增大镜像体积。
 - 先安装系统依赖,再 COPY 频繁变动的二进制,可最大化利用缓存、加速构建。
 建议改为:
-RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \ - && apk upgrade && apk add --no-cache curl bash inotify-tools alpine-conf busybox-extras tzdata aws-cli helm tar gzip\ - && apk del alpine-conf && rm -rf /var/cache/* && chmod +x k8m && chmod +x /app/reload.sh +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \ + && apk add --no-cache curl bash inotify-tools alpine-conf busybox-extras tzdata aws-cli helm tar gzip \ + && apk del alpine-conf && rm -rf /var/cache/*如需进一步瘦身/加速:考虑将 aws-cli/helm 放入独立镜像或按需安装。
21-21: ENTRYPOINT 建议参数化,避免 BINARY_NAME 与硬编码不一致当前硬编码 "k8m",若修改 BINARY_NAME 将不一致。
-ENTRYPOINT ["/app/reload.sh", "k8m", "/app"] +ENTRYPOINT ["/app/reload.sh", "k8m", "/app"]或将 reload.sh 兼容从环境变量读取可执行名,例如:/app/$BINARY_NAME。若 reload.sh 已支持参数传入,可改为:
-ENTRYPOINT ["/app/reload.sh", "k8m", "/app"] +ENTRYPOINT ["/app/reload.sh", "${BINARY_NAME}", "/app"](提示:JSON 形式不做环境变量扩展,需在构建期替换或在 reload.sh 内读取 BINARY_NAME 环境变量。)
.github/workflows/build-release.yml (1)
17-21: Node.js 18 已到 EOL,建议升级到 20 LTS减少未来安全与供应风险,Node 20 为当前 LTS。
- - name: 使用 Node.js - uses: actions/setup-node@v5 - with: - node-version: 18 + - name: 使用 Node.js + uses: actions/setup-node@v5 + with: + node-version: 20 cache: "pnpm" cache-dependency-path: "ui/pnpm-lock.yaml".github/workflows/build-docker-image.yml (3)
41-45: Node.js 18 已到 EOL,建议升级到 20 LTS与发布流程保持一致,降低维护风险。
- - name: 使用 Node.js - uses: actions/setup-node@v5 - with: - node-version: 18 + - name: 使用 Node.js + uses: actions/setup-node@v5 + with: + node-version: 20 cache: "pnpm" cache-dependency-path: "ui/pnpm-lock.yaml"
75-77: set-output 已废弃,改用 GITHUB_OUTPUT避免后续 GitHub Actions 行为变化导致失败。
- - name: Get current date - id: date - run: echo "::set-output name=today::$(date +'%Y%m%d-%H%M')" + - name: Get current date + id: date + run: echo "today=$(date +'%Y%m%d-%H%M')" >> $GITHUB_OUTPUT
120-129: 引用分支/标签名建议使用 slug 变量,避免非法字符github-slug-action 会导出 GITHUB_REF_SLUG,更稳妥。
- ${{ env.DOCKERHUB_USERNAME }}/${{ env.IMAGE_REPONAME }}:${{ env.GITHUB_REF_NAME }} - ${{ env.ALIHUB_URL }}/${{ env.ALIHUB_IMAGE_REPONAME }}/${{ env.IMAGE_REPONAME }}:${{ env.GITHUB_REF_NAME }} + ${{ env.DOCKERHUB_USERNAME }}/${{ env.IMAGE_REPONAME }}:${{ env.GITHUB_REF_SLUG }} + ${{ env.ALIHUB_URL }}/${{ env.ALIHUB_IMAGE_REPONAME }}/${{ env.IMAGE_REPONAME }}:${{ env.GITHUB_REF_SLUG }} - ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_REPONAME }}:${{ env.GITHUB_REF_NAME }} + ghcr.io/${{ github.repository_owner }}/${{ env.IMAGE_REPONAME }}:${{ env.GITHUB_REF_SLUG }}确认 rlespinasse/github-slug-action@v4 确实在当前作业环境导出了该环境变量(默认会导出)。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
.dockerignore(0 hunks).github/workflows/build-docker-image.yml(4 hunks).github/workflows/build-release.yml(1 hunks)Dockerfile.action(1 hunks)Makefile(1 hunks)
💤 Files with no reviewable changes (1)
- .dockerignore
 
🧰 Additional context used
🪛 Hadolint (2.14.0)
Dockerfile.action
[error] 11-11: Use COPY instead of ADD for files and folders
(DL3020)
🔇 Additional comments (1)
Makefile (1)
42-43: 扩展到 amd64/arm64 很好,和 CI 多架构一致与 Dockerfile.action 的 TARGETARCH 命名和 CI 的 platforms 一致,方向正确。
请确认 .github/workflows/build-docker-image.yml 的 platforms 与这里保持完全一致(当前为 linux/amd64,linux/arm64),避免某一侧漏配导致镜像缺架构。
| - name: 编译后端 | ||
| run: | | ||
| make build-linux GIT_COMMIT=${{ github.sha }} GIT_TAG=${{ github.ref_name }} GIT_REPOSITORY=${{ github.repository }} BUILD_DATE=${{ env.BUILD_TIME }} VERSION=${{ github.ref_name }} MODEL=${{ env.OPENAI_API_MODEL }} API_KEY=${{ secrets.OPENAI_API_KEY }} API_URL=${{ env.OPENAI_API_URL }} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
严重:将 OPENAI_API_KEY 烘焙进镜像二进制(泄露机密)
与 release 流程同样问题:密钥通过 -ldflags 注入,最终进入公开镜像。
删除编译期注入的 API_KEY,运行期通过环境变量注入:
-          make build-linux GIT_COMMIT=${{ github.sha }} GIT_TAG=${{ github.ref_name }} GIT_REPOSITORY=${{ github.repository }} BUILD_DATE={{ env.BUILD_TIME }} VERSION=${{ github.ref_name }} MODEL=${{ env.OPENAI_API_MODEL }} API_KEY=${{ secrets.OPENAI_API_KEY }} API_URL=${{ env.OPENAI_API_URL }}
+          make build-linux GIT_COMMIT=${{ github.sha }} GIT_TAG=${{ github.ref_name }} GIT_REPOSITORY=${{ github.repository }} BUILD_DATE=${{ env.BUILD_TIME }} VERSION=${{ github.ref_name }} MODEL=${{ env.OPENAI_API_MODEL }} API_URL=${{ env.OPENAI_API_URL }}随后在部署时以 env 方式传入 OPENAI_API_KEY(不写入镜像/二进制)。
我可以同步给出应用读取环境变量的代码改动建议。
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: 编译后端 | |
| run: | | |
| make build-linux GIT_COMMIT=${{ github.sha }} GIT_TAG=${{ github.ref_name }} GIT_REPOSITORY=${{ github.repository }} BUILD_DATE=${{ env.BUILD_TIME }} VERSION=${{ github.ref_name }} MODEL=${{ env.OPENAI_API_MODEL }} API_KEY=${{ secrets.OPENAI_API_KEY }} API_URL=${{ env.OPENAI_API_URL }} | |
| - name: 编译后端 | |
| run: | | |
| make build-linux GIT_COMMIT=${{ github.sha }} GIT_TAG=${{ github.ref_name }} GIT_REPOSITORY=${{ github.repository }} BUILD_DATE=${{ env.BUILD_TIME }} VERSION=${{ github.ref_name }} MODEL=${{ env.OPENAI_API_MODEL }} API_URL=${{ env.OPENAI_API_URL }} | 
🤖 Prompt for AI Agents
.github/workflows/build-docker-image.yml around lines 67-70: the workflow is
passing OPENAI_API_KEY into the build command which causes the secret to be
baked into the binary; remove API_KEY from the make build invocation and any
ldflags that inject it into the binary, update the Makefile/build scripts to
accept no compile-time API key (keep MODEL/API_URL/etc. if needed) and ensure
the application reads OPENAI_API_KEY at runtime from process environment
variables; finally document or update deployment manifests to supply
OPENAI_API_KEY as an environment variable (secrets) to containers instead of
embedding it during build.
如题。