--- title: Cache management with GitHub Actions keywords: ci, github actions, gha, buildkit, buildx, cache --- This page contains examples on using the cache storage backends with GitHub Actions. > [!NOTE] > > See [Cache storage backends](../../cache/backends/_index.md) for more > details about cache storage backends. ## Inline cache In most cases you want to use the [inline cache exporter](../../cache/backends/inline.md). However, note that the `inline` cache exporter only supports `min` cache mode. To use `max` cache mode, push the image and the cache separately using the registry cache exporter with the `cache-to` option, as shown in the [registry cache example](#registry-cache). ```yaml name: ci on: push: jobs: docker: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ vars.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v6 with: push: true tags: user/app:latest cache-from: type=registry,ref=user/app:latest cache-to: type=inline ``` ## Registry cache You can import/export cache from a cache manifest or (special) image configuration on the registry with the [registry cache exporter](../../cache/backends/registry.md). ```yaml name: ci on: push: jobs: docker: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ vars.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v6 with: 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 cache ### Cache backend API {{% experimental %}} This cache exporter is experimental. Please provide feedback on the [BuildKit repository](https://github.com/moby/buildkit) if you experience any issues. {{% /experimental %}} The [GitHub Actions cache exporter](../../cache/backends/gha.md) backend uses the [GitHub Cache API](https://github.com/tonistiigi/go-actions-cache/blob/master/api.md) to fetch and upload cache blobs. That's why you should only use this cache backend in a GitHub Action workflow, as the `url` (`$ACTIONS_CACHE_URL`) and `token` (`$ACTIONS_RUNTIME_TOKEN`) attributes only get populated in a workflow context. ```yaml name: ci on: push: jobs: docker: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ vars.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v6 with: push: true tags: user/app:latest cache-from: type=gha cache-to: type=gha,mode=max ``` ### Cache mounts BuildKit doesn't preserve cache mounts in the GitHub Actions cache by default. If you wish to put your cache mounts into GitHub Actions cache and reuse it between builds, you can use a workaround provided by [`reproducible-containers/buildkit-cache-dance`](https://github.com/reproducible-containers/buildkit-cache-dance). This GitHub Action creates temporary containers to extract and inject the cache mount data with your Docker build steps. The following example shows how to use this workaround with a Go project. Example Dockerfile in `build/package/Dockerfile` ```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 ... ``` Example CI action ```yaml name: ci on: push: jobs: build: runs-on: ubuntu-latest steps: - 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@v4 with: path: go-build-cache key: ${{ runner.os }}-go-build-cache-${{ hashFiles('**/go.sum') }} - name: inject go-build-cache into docker uses: reproducible-containers/buildkit-cache-dance@4b2444fec0c0fb9dbf175a96c094720a692ef810 # v2.1.4 with: cache-source: go-build-cache - name: Build and push uses: docker/build-push-action@v6 with: 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 ``` For more information about this workaround, refer to the [GitHub repository](https://github.com/reproducible-containers/buildkit-cache-dance). ### Local cache > [!WARNING] > > At the moment, old cache entries aren't deleted, so the cache size [keeps growing](https://github.com/docker/build-push-action/issues/252). > The following example uses the `Move cache` step as a workaround (see [`moby/buildkit#1896`](https://github.com/moby/buildkit/issues/1896) > for more info). You can also leverage [GitHub cache](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows) using the [actions/cache](https://github.com/actions/cache) and [local cache exporter](../../cache/backends/local.md) with this action: ```yaml name: ci on: push: jobs: docker: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Cache Docker layers uses: actions/cache@v4 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: ${{ vars.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v6 with: 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 ```