buildx のキャッシュ戦略
buildx で使える 3 種類のキャッシュ(registry / gha / inline)の特徴と使い分け、そして CI のビルド時間を実際に短縮するためのコツ。
なぜ buildx のキャッシュが重要か
CI は毎回真っさらなランナーでビルドするため、ローカルの docker build のようなレイヤーキャッシュがそのまま使えません。
キャッシュを明示的に外部化しないと、毎回 npm install / pip install / go mod download をゼロからやり直すことになります。
buildx のキャッシュ機能を使うと、前回のビルドで作ったレイヤーを外部ストレージに保存し、次回ビルド時に再利用できます。
小〜中規模のプロジェクトで ビルド時間を 50〜80% 短縮 できることが多いです。
3 種類のキャッシュバックエンド
| バックエンド | 書式 | 保存先 | 向いている場面 |
|---|---|---|---|
gha |
type=gha,mode=max |
GitHub Actions のキャッシュストレージ(リポジトリに紐づく、上限 10GB) | GitHub Actions 単独で完結させたい場合。セットアップが最も簡単 |
registry |
type=registry,ref=...:cache |
任意のコンテナレジストリ | 複数の CI 間で共有したい、GHA の 10GB 制限を超える大規模プロジェクト |
inline |
type=inline |
イメージ本体にキャッシュメタを埋め込む | レジストリキャッシュの簡易版。別タグを持たなくて良い反面、mode=min 相当で効果は限定的 |
マネージド CI(GitHub Actions)なら gha が第一選択。
レジストリ側にも制約がなく、複数マシンで共有したいなら registry に切り替えるのが定石です。
gha キャッシュの書き方
gha キャッシュは Actions の ACTIONS_CACHE_URL / ACTIONS_RUNTIME_TOKEN を内部で使います。
docker/build-push-action がこれらを自動的に渡してくれるため、指定は次の 2 行だけで足ります。
mode=max は全ステージのキャッシュを保存(マルチステージビルド全てを含む)、mode=min(デフォルト)は最終ステージだけ。
CI では max 推奨です。
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=maxregistry キャッシュの書き方
別タグ(例: :cache)としてキャッシュ用マニフェストを push します。
GHCR・ECR・Docker Hub などマニフェストリスト対応の OCI 互換レジストリならどこでも動きます。
mode=max 推奨です。
初回は完全にキャッシュミスしますが、2 回目以降の短縮効果が大きいのが特徴です。
また、本番イメージと同じレジストリに置けばネットワーク的にも近く、CI↔キャッシュの転送コストが小さくなります。
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
cache-from: type=registry,ref=ghcr.io/${{ github.repository }}:buildcache
cache-to: type=registry,ref=ghcr.io/${{ github.repository }}:buildcache,mode=max,compression=zstdキャッシュ効果を最大化するコツ
- Dockerfile のレイヤー順を見直す: 変わりにくいものを上に、変わりやすいものを下に。
COPY package*.json ./ && npm ciを先、COPY . .を後に置くと、ソース変更時でもnpm ciはキャッシュヒットする .dockerignoreを厳しくする:node_modulesや.gitが入るとハッシュが毎回変わり、キャッシュがほとんど使えなくなる--cache-fromは複数指定できる: PR のキャッシュ(リリースブランチ)と main のキャッシュの両方をcache-fromに列挙すると、ヒット率が上がる- マトリクスビルドでは branch 込みのキー: 別 OS / 別アーキのジョブがキャッシュを踏み潰さないよう、
ref=.../buildcache-linux-amd64のようにアーキ込みで命名する mode=maxのディスク使用量に注意: 10GB 制限を超えると古いキャッシュから順に evict される。巨大プロジェクトはregistryへの切り替えを検討- pull_request で
cache-toを動かすときの注意: fork 元 PR では書き込み権限がないため失敗する。cache-to: ${{ github.event_name == 'push' && 'type=gha,mode=max' || '' }}のように push 時だけに制限するか、cache-fromだけにする
