使用 GitHub Actions 进行缓存管理

本页面包含有关将缓存存储后端与 GitHub Actions 结合使用的示例。

笔记

有关缓存存储后端的更多详细信息,请参阅 缓存存储后端。

内联缓存

在大多数情况下,您希望使用 内联缓存导出器。但请注意,inline缓存导出器仅支持min缓存模式。要使用max缓存模式,请使用带有选项的注册表缓存导出器分别推送映像和缓存,如注册表缓存示例cache-to所示 。

name: ci

on:
  push:
    branches:
      - "main"

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: user/app:latest
          cache-from: type=registry,ref=user/app:latest
          cache-to: type=inline

注册表缓存

您可以使用注册表缓存导出器从注册表上的缓存清单或(特殊)图像配置导入/导出缓存 。

name: ci

on:
  push:
    branches:
      - "main"

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: user/app:latest
          cache-from: type=registry,ref=user/app:buildcache
          cache-to: type=registry,ref=user/app:buildcache,mode=max

GitHub 缓存

缓存后端API

实验性的

该缓存导出器是实验性的。 如果您遇到任何问题,请在BuildKit 存储库上提供反馈 。

GitHub Actions 缓存导出器 后端使用 GitHub Cache API 来获取和上传缓存 blob。这就是为什么您应该仅在 GitHub Action 工作流程中使用此缓存后端,因为url( $ACTIONS_CACHE_URL) 和 token( $ACTIONS_RUNTIME_TOKEN) 属性仅在工作流程上下文中填充。

name: ci

on:
  push:
    branches:
      - "main"

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: user/app:latest
          cache-from: type=gha
          cache-to: type=gha,mode=max

缓存挂载

默认情况下,BuildKit 不会在 GitHub Actions 缓存中保留缓存挂载。如果您希望将缓存挂载放入 GitHub Actions 缓存并在构建之间重用它,您可以使用 reproducible-containers/buildkit-cache-dance.

此 GitHub Action 创建临时容器,以通过 Docker 构建步骤提取和注入缓存挂载数据。

以下示例展示了如何在 Go 项目中使用此解决方法。

示例 Dockerfile 位于build/package/Dockerfile

FROM golang:1.21.1-alpine as base-build

WORKDIR /build
RUN go env -w GOMODCACHE=/root/.cache/go-build

COPY go.mod go.sum ./
RUN --mount=type=cache,target=/root/.cache/go-build go mod download

COPY ./src ./
RUN --mount=type=cache,target=/root/.cache/go-build go build -o /bin/app /build/src
...

CI 操作示例

name: ci
on: push

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

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

      - name: Docker meta
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: YOUR_IMAGE
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}            

      - name: Go Build Cache for Docker
        uses: actions/cache@v3
        with:
          path: go-build-cache
          key: ${{ runner.os }}-go-build-cache-${{ hashFiles('**/go.sum') }}

      - name: inject go-build-cache into docker
        # v1 was composed of two actions: "inject" and "extract".
        # v2 is unified to a single action.
        uses: reproducible-containers/buildkit-cache-dance@v2.1.2
        with:
          cache-source: go-build-cache

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          cache-from: type=gha
          cache-to: type=gha,mode=max
          file: build/package/Dockerfile
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          platforms: linux/amd64,linux/arm64

有关此解决方法的更多信息,请参阅 GitHub 存储库

本地缓存

警告

目前,旧的缓存条目没有被删除,因此缓存大小 不断增长。以下示例使用该Move cache步骤作为解决方法(请参阅 参考资料 moby/buildkit#1896 获取更多信息)。

您还可以 通过以下操作 使用 actions/cache本地缓存导出器来利用GitHub 缓存:

name: ci

on:
  push:
    branches:
      - "main"

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Cache Docker layers
        uses: actions/cache@v3
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-buildx-            
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: user/app:latest
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
      - # Temp fix
        # https://github.com/docker/build-push-action/issues/252
        # https://github.com/moby/buildkit/issues/1896
        name: Move cache
        run: |
          rm -rf /tmp/.buildx-cache
          mv /tmp/.buildx-cache-new /tmp/.buildx-cache