You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CI流水线排障:代码变更未同步到Docker镜像

问题:代码变更未同步到Docker镜像(仅修改标签生效)

修改代码并推送后,CI流水线触发构建并推送Docker镜像至GitHub Container Registry,但拉取镜像时代码变更未生效。只有修改镜像标签时,新变更才会出现在新构建的镜像中。

提供的CI配置文件

name: Continuous Integration

on:
  push:
    branches:
      - main

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Log in to the Container registry
        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Build and push Docker image
        uses: docker/build-push-action@v2
        with:
          context: .
          push: true
          tags: ghcr.io/${{ github.repository_owner }}/myreponame:new

提供的Dockerfile

# Build stage
FROM maven:3-openjdk-17-slim AS build
COPY src /home/app/src
COPY pom.xml /home/app/pom.xml
COPY wait-for-it.sh /home/app/wait-for-it.sh
RUN chmod +x /home/app/wait-for-it.sh
RUN mvn -f /home/app/pom.xml clean package

# Package stage
FROM openjdk:17-alpine
RUN apk add --no-cache bash
COPY --from=build /home/app/target/api.jar /usr/local/lib/api.jar
COPY --from=build /home/app/wait-for-it.sh /usr/local/bin/wait-for-it.sh
ENTRYPOINT ["/usr/local/bin/wait-for-it.sh", "db:5432", "--", "java", "-jar", "/usr/local/lib/api.jar"]

问题原因

  1. 镜像标签重复覆盖导致缓存命中:每次构建都使用固定标签new推送到仓库,虽然仓库内的镜像已更新,但拉取镜像的环境(本地服务器、容器编排工具)会优先使用本地缓存的旧镜像,不会主动拉取最新的同名标签镜像。
  2. 可选:构建层缓存复用:Docker Buildx默认会复用之前的构建层,如果代码变更未触发构建层失效,可能导致构建出的镜像未包含最新代码。

解决方案

1. 使用动态唯一标签(推荐)

为每次构建生成唯一标签(如提交哈希、运行编号),避免标签重复带来的缓存问题,同时保留固定标签作为稳定版指向:
修改CI配置中Build and push Docker image步骤的tags字段:

tags: |
  ghcr.io/${{ github.repository_owner }}/myreponame:new
  ghcr.io/${{ github.repository_owner }}/myreponame:${{ github.sha }}
  ghcr.io/${{ github.repository_owner }}/myreponame:${{ github.run_number }}
  • ${{ github.sha }}:当前提交的完整哈希值,唯一对应代码版本
  • ${{ github.run_number }}:CI流水线的递增运行编号
    拉取时可指定唯一标签确保获取对应版本,或通过固定标签配合强制拉取更新。

2. 拉取时强制刷新缓存

若坚持使用固定标签,拉取镜像时添加--pull always参数强制拉取仓库最新版本:

docker pull ghcr.io/${{ github.repository_owner }}/myreponame:new --pull always

运行容器时也可直接指定:

docker run --pull always ghcr.io/${{ github.repository_owner }}/myreponame:new

3. 禁用构建缓存确保代码全量构建

在docker/build-push-action中添加no-cache: true,强制每次构建不复用旧构建层,确保代码变更被正确打包:

- name: Build and push Docker image
  uses: docker/build-push-action@v2
  with:
    context: .
    push: true
    no-cache: true
    tags: ghcr.io/${{ github.repository_owner }}/myreponame:new

注意:此操作会增加构建时间,建议结合动态标签使用,或仅在排查问题时启用。


内容的提问来源于stack exchange,提问作者Johni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 18:47:44