📖

docker buildxのtype=local・ghaのキャッシュ保存を比較

に公開

docker buildxとは

Docker による ビルド機能の拡張する CLI プラグインです。BuildKitを内部的に利用しているラッパー(インターフェイス)です。
https://matsuand.github.io/docs.docker.jp.onthefly/buildx/working-with-buildx/

たとえば、下記のようなことができます。

機能 説明
高速ビルド BuildKit による並列処理・効率的なキャッシュ利用で速くなります
マルチプラットフォーム対応 --platform=linux/amd64,linux/arm64 などで複数アーキテクチャのイメージを一括ビルド
キャッシュの柔軟な活用 --cache-from--cache-to でキャッシュの共有が可能(ローカル、レジストリ、GitHub Actionsなど)
リモートビルド Docker Desktop や GitHub Actions で、ビルダーインスタンスを使いリモートビルドが可能
Dockerfile の機能強化 RUN --mount=type=cache など BuildKit 拡張機能を使える

type=local OR type=gha

--cache-to の type によってキャッシュの保存場所が異なります。

  • type=local: ランナー上のローカルに保存
  • type=gha: GitHub Actions のキャッシュストレージに保存

buildxを利用したbuildとtype=localへの保存

  1. name: Checkout
    github リポジトリをチェックアウトしてきます。
    ※ docker/backend/DockerfileにDockerfileが存在していることを前提にしています。

  2. name: check before buildx docker container

  3. name: check before buildx docker images

  4. name: List local before cache contents
    buildする前に確認してみます。全てデータは存在しません。

  5. name: Build with local cache
    docker/backend/Dockerfileをbuildします。また、type=localで、runner(= local)の/tmp/buildx-local-cacheに対して、キャッシュしていきます。

  6. name: check after buildx docker container
    コンテナが生成されています。
    docker buildx create --useにて、moby/buildkit:buildx-stable-1のコンテナが生成されます。このコンテナ内部でbuildxはbuild処理などをします。

CONTAINER ID   IMAGE                           COMMAND                  CREATED          STATUS          PORTS     NAMES
97c4d35b1e9e   moby/buildkit:buildx-stable-1   "buildkitd --allow-i…"   18 seconds ago   Up 18 seconds             buildx_buildkit_affectionate_galois0
  1. name: check after buildx docker images
    imageが2つできています。
    moby/buildkitはbuildx用のコンテナを作るimageです。
    <none>はbuildxによって生成されたimageの成果物です。
REPOSITORY      TAG               IMAGE ID       CREATED          SIZE
<none>          <none>            67ae501d550c   10 seconds ago   453MB
moby/buildkit   buildx-stable-1   8124f5e2ddf9   3 weeks ago      209MB
  1. name: List local after cache contents
    runnerの/tmp/buildx-local-cache配下にキャッシュファイルが生成されているのが分かります。
/tmp/buildx-local-cache
/tmp/buildx-local-cache/ingest
/tmp/buildx-local-cache/oci-layout
/tmp/buildx-local-cache/index.json
/tmp/buildx-local-cache/blobs
// 省略
/tmp/buildx-local-cache/blobs/sha256/75f44a7fe0ad4523195f1bfcdb7dd9bde594700c0e21dc438c40855b1294e1e9
/tmp/buildx-local-cache/blobs/sha256/b77624d12267cd5c0a007459a26434d33335fb6b5dbd2a266d481794293c147b
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: check before buildx docker container
        run: |
          echo "Listing buildx docker containers:"
          docker ps -a

      - name: check before buildx docker images
        run: |
          echo "Listing buildx docker images:"
          docker images

      - name: List local before cache contents
        run: |
          echo "Listing cache directory:"
          find /tmp/buildx-local-cache || echo "No cache found"

      - name: Build with local cache
        run: |
          mkdir -p /tmp/buildx-local-cache
          docker buildx create --use
          docker buildx build \
            --cache-to=type=local,dest=/tmp/buildx-local-cache \
            --cache-from=type=local,src=/tmp/buildx-local-cache \
            --output=type=docker \
            -f docker/backend/Dockerfile .

      - name: check after buildx docker container
        run: |
          echo "Listing buildx docker containers:"
          docker ps -a

      - name: check after buildx docker images
        run: |
          echo "Listing buildx docker images:"
          docker images

      - name: List local after cache contents
        run: |
          echo "Listing cache directory:"
          find /tmp/buildx-local-cache || echo "No cache found"

type=localからactionsのキャッシュストレージへ保存

前述したように、buildxのtype=localを利用してrunnerのホスト環境にキャッシュを生成することはできました。しかし、actionsのキャッシュストレージにはキャッシュは保存されていません。

actions/cacheを利用して、キャッシュストレージに保存してみます。
参考:
https://zenn.dev/osachi/articles/46a63d57622fd1

  1. name: cache actions
    path: /tmp/buildx-local-cacheに対して、キャッシュの作成・復元を試みます。

  2. name: Build with local cache
    変わらないです。localの/tmp/buildx-local-cacheに対してキャッシュを生成します。ここで生成されたら、actions/cache@v4によって、actionsのキャッシュストレージへ保存されます。

  3. name: List local after cache contents
    変わらないです。localの/tmp/buildx-local-cacheに対してキャッシュファイルを確認できます。

  4. Post cache actions (stepとして明示していないが、自動で実行される)
    Cache saved with key: Linux-buildx-2d1d...abf8 で、キャッシュファイルがsentされているのが分かります。

Post job cleanup.
/usr/bin/tar --posix -cf cache.tzst --exclude cache.tzst -P -C /home/runner/work/photoruction-site-v2/photoruction-site-v2 --files-from manifest.txt --use-compress-program zstdmt
Sent 24803670 of 159021398 (15.6%), 23.7 MBs/sec
Sent 159021398 of 159021398 (100.0%), 108.9 MBs/sec
Cache saved with key: Linux-buildx-2d1d01adc1defc101faa4bd8ebda3b8bd4cf46d12e21aa16f4060a258137abf8
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      
      - name: cache actions
        uses: actions/cache@v4
        with:
          path: /tmp/buildx-local-cache
          key: ${{ runner.os }}-buildx-${{ hashFiles('docker/backend/Dockerfile') }}

      - name: Build with local cache
        run: |
          mkdir -p /tmp/buildx-local-cache
          docker buildx create --use
          docker buildx build \
            --cache-to=type=local,dest=/tmp/buildx-local-cache \
            --cache-from=type=local,src=/tmp/buildx-local-cache \
            --output=type=docker \
            -f docker/backend/Dockerfile .

      - name: List local after cache contents
        run: |
          echo "Listing cache directory:"
          find /tmp/buildx-local-cache || echo "No cache found"

再度、worflowを実行するとcacheが効きます。actions/cacheがキャシュを取得してくるので、buildxがcache-from=type=local,src=/tmp/buildx-local-cacheを確認してキャッシュの利用が出来るようになります。

docker/build-push-action / docker/setup-buildx-actionを利用

実際に、github actionsを利用してbuildxを使う場合は、ライブラリを利用することが多いと思います。
下記設定で、runnerの/tmp/buildx-local-cacheに対してキャッシュファイルを保存します。

jobs:
  build:
    runs-on: ubuntu-latest
    steps:

      - name: Checkout
        uses: actions/checkout@v4
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          use: true

      - name: Build with local cache
        uses: docker/build-push-action@v5
        with:
          context: .
          file: docker/backend/Dockerfile
          push: false
          outputs: type=docker
          cache-from: type=local,src=/tmp/buildx-local-cache
          cache-to: type=local,dest=/tmp/buildx-local-cache

      - name: List local after cache contents
        run: |
          echo "Listing cache directory:"
          find /tmp/buildx-local-cache || echo "No cache found"

type=ghaでactionsのキャッシュストレージへ保存

type=ghaを利用して、actionsのキャッシュストレージへ保存します。
actions/cacheを利用しなくても、type=ghaを利用することでactionsのキャッシュストレージへ直接保存します。

name: List local after cache contents では、localにキャッシュファイルを出力していないので、echo "No cache found"となります。

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

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          driver-opts: image=moby/buildkit:latest

      - name: Login to DockerHub (if needed)
        run: echo "スキップするか、ログイン必要なら記述"

      - name: Build and cache using GHA
        uses: docker/build-push-action@v5
        with:
          context: .
          file: docker/backend/Dockerfile
          push: false
          load: true  # or output: type=docker に相当(ローカル実行用)
          provenance: false
          cache-from: type=gha,id=backend
          cache-to: type=gha,mode=max,id=backend

      - name: List local after cache contents
        run: |
          echo "Listing cache directory:"
          find /tmp/buildx-local-cache || echo "No cache found"

Discussion