docker / build-push-action

GitHub Action to build and push Docker images with Buildx
https://github.com/marketplace/actions/build-and-push-docker-images
Apache License 2.0
4.11k stars 527 forks source link

How to clear the builder cache? #1002

Closed Yongci closed 7 months ago

Yongci commented 7 months ago

Contributing guidelines

I've found a bug, and:

Description

Whenever I change the code, it still uses the cache file to build the image, and the changed code never takes effect? Does anyone know how to solve it?

image

Expected behaviour

we don't need the build cache

Actual behaviour

Those cache files are hit on every build, weird

Repository URL

No response

Workflow run URL

No response

YAML workflow

# action.yaml
      - name: "List files and clean up the builder cache"
        run: |
          ls -lah && \
          docker builder prune -f

      - name: "Build and push container image"
        id: build-and-push
        uses: docker/build-push-action@v4
        with:
          context: ${{ inputs.DOCKERFILE }}
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

# Dockerfile

FROM xxxxxxxx.azurecr.io/baseimage/apache-maven:v3.9.5-20231017-jdk11 AS build-stage

ENV PROJ_NAME services

WORKDIR /home/hub

COPY . /home/hub/$PROJ_NAME

RUN cd /home/hub/services && mvn clean install -DskipTests -Dmaven.javadoc.skip=true

RUN cd /home/hub/services && ls -l

FROM xxxxxxx.azurecr.io/baseimage/openjdk:11.0.18.2-patch-202304

ENV PROJ_NAME services

WORKDIR /home/hub

COPY --from=build-stage /home/hub/$PROJ_NAME/* ./
RUN ls -la

Workflow logs

No response

BuildKit logs

No response

Additional info

No response

crazy-max commented 7 months ago

Can you show the full workflow? Seems you're using a self-hosted if BuildKit state is retained on the runner right?

Whenever I change the code, it still uses the cache file to build the image, and the changed code never takes effect?

Are you sure these changes affects your context though? What is the value of ${{ inputs.DOCKERFILE }}? Would need full workflow logs to understand how it affects your build.

If you can create a simple repro on a public repository that would be ideal. Thanks.

Yongci commented 7 months ago

${{ inputs.DOCKERFILE }} = "."

Full workflow YAML:

name: maven-compile

on:
  workflow_call:
    inputs:
      REPOSITORY:
        required: true
        type: string
        description: "Your code repository URL."
      REPOSITORY_REF:
        required: false
        type: string
        description: "Your repository branch or tag or SHA string."
      JDK_VERSION:
        required: true
        type: string
        default: "8"
        description: "Select JDK version."
      UNIT_TEST:
        required: false
        type: string
        default: 'false'
        description: "If your want to run the unit test."
      UNIT_TEST_SCRIPT:
        required: false
        type: string
        default: "npm run test"
        description: "Setup your unit test script name or path."
      APP_NAME:
        required: true
        type: string
        description: "Your application name."
      DOCKERFILE:
        required: false
        type: string
        default: "."
        description: "Your Dockerfile path."
      PROJECT:
        required: false
        type: string
        default: "hubkube"
        description: "You want push to which container registry folder."
      BUILD_SCRIPT:
        required: false
        type: string
        default: "./compile.sh"
        description: "Your build script path."
      SONARQUBE:
        required: false
        type: string
        default: 'false'
        description: "If your want to run the SonarQube scan."
      CONTAINER_IMAGE_SCAN:
        required: false
        type: string
        default: 'false'
        description: "If your want to run the container image scan."
      SRC_DIR:
        required: true
        type: string
        description: "Your repository src folder path."

    secrets:
      PLATFORM_GITHUBBOT_TOKEN:
        required: true
        description: "Platform team GitHub bot service account token."
      PLATFORM_ACR_SECRET:
        required: true
        description: "Platform team Azure Container Registry password."
      SONAR_TOKEN:
        required: false
        description: "Your SonarQube token."
      SONAR_HOST_URL:
        required: false
        description: "Your SonarQube URL."
      SONAR_ROOT_CERT:
        required: false
        description: "Your SonarQube root certificate."

jobs:
  Compile:
    env:
      CONTAINER_REGISTRY: "xxxxxxx.azurecr.io"
      CONTAINER_REGISTRY_PROJECT: ${{ inputs.PROJECT }}

    runs-on:
      labels:
        - "Linux"
        - "X64"
        - "Ubuntu"
        - "self-hosted"
      group: "ITCOLO-Platform-Runners"

    steps:
      - name: "Checkout to your repository branch"
        uses: actions/checkout@v3
        with:
          github-server-url: "https://xxxxxx.com"
          repository: ${{ inputs.REPOSITORY }}
          ref: ${{ inputs.REPOSITORY_REF }}
          token: ${{ secrets.PLATFORM_GITHUBBOT_TOKEN }}

      - name: "Set up QEMU VMs"
        uses: docker/setup-qemu-action@v2

      - name: "Set up the Docker Buildx tool"
        uses: docker/setup-buildx-action@v2
        with:
          platforms: linux/amd64
          driver-opts: network=host

      - name: "Log into registry ${{ env.CONTAINER_REGISTRY }}"
        uses: docker/login-action@v2
        with:
          registry: ${{ env.CONTAINER_REGISTRY }}
          username: ${{ vars.PLATFORM_ACR_USERNAME }}
          password: ${{ secrets.PLATFORM_ACR_SECRET }}

      - name: "Extract container metadata"
        id: meta
        uses: docker/metadata-action@v4
        with:
          images: ${{ env.CONTAINER_REGISTRY }}/${{ env.CONTAINER_REGISTRY_PROJECT }}/${{ inputs.APP_NAME }}

      - name: "List files and clean up the builder cache"
        run: |
          ls -lah && \
          docker builder prune -f

      - name: "Build and push container image"
        id: build-and-push
        uses: docker/build-push-action@v4
        with:
          context: ${{ inputs.DOCKERFILE }}
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

      - name: "Sign the published container image"
        id: sign-image-tag
        env:
          TAGS: ${{ steps.meta.outputs.tags }}
          DIGEST: ${{ steps.build-and-push.outputs.digest }}
        run: |
          #echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
          echo "IMAGE_TAGS_DIGEST=${TAGS}@${DIGEST}" | tee >> $GITHUB_OUTPUT
crazy-max commented 7 months ago

Ok so you're using a self-hosted runner, in this case BuildKit state persists.

COPY --from=build-stage is not pruned as it's most likely a shared layer because it was exported (as an image). For such case you need to use docker builder prune --all. You can also check current disk usage with docker buildx du and docker buildx du --verbose if you want more info. See https://github.com/docker/buildx/blob/master/docs/reference/buildx_du.md

I'm not sure why you want to prune your builder for each run though. It's more like an administrative task and should not be part of your workflow imo.