# Docker レイヤーキャッシュ

> Latchkey Docker Cache Build は docker buildx をレジストリバックのレイヤーキャッシュでラップします。そのため、繰り返しのイメージビルドでは、エフェメラルなランナーをまたいで変更されていないすべてのレイヤーを再利用します。

Source: https://latchkey.dev/ja/documentation/docker-layer-caching

## Summary

- 1 つのステップ: `latchkey-dev/docker-cache-action@v1` が `docker buildx build` をレジストリバックのレイヤーキャッシュでラップします。
- レイヤーは Latchkey の使い捨てランナーをまたいで永続化されます。変更によって無効化されたレイヤーだけが再ビルドされます。
- 設定不要: キャッシュレジストリ、認証情報、権限は組織ごとにあらかじめプロビジョニングされています。
- ポータブル: Latchkey 以外のランナーでは、同じステップがレジストリを検出せず、キャッシュフラグなしで通常どおりビルドします。

すべての Latchkey ランナーは、新しく分離されたインスタンスです。これはセキュリティには良い一方、ランナーとともに消えてしまう Docker のローカルレイヤーキャッシュには不都合です。**Latchkey Docker Cache Build** は、Latchkey が組織向けに管理するプライベートコンテナレジストリに保存されたレイヤーキャッシュでこれを解決します。以前のビルドと一致するレイヤーが再利用され、更新されたキャッシュは次回の実行のために書き戻されます。

## ワークフローに追加する

```.github/workflows/build.yml
jobs:
  build:
    runs-on: latchkey-medium
    steps:
      - uses: actions/checkout@v4
      - uses: latchkey-dev/docker-cache-action@v1
        with:
          context: .
          tags: myapp:latest
          push: true
```

これで統合は完了です。任意の Docker ビルドに渡すのと同じ入力を指定するだけで、Latchkey がレジストリ、認証情報、キャッシュの接続を処理します。デフォルトでは、この action は `cache-mode: max` を使用し、マルチステージビルドの中間レイヤーを含むすべてのレイヤーをキャッシュします。`push: false` の単一プラットフォームビルドでは、ビルドされたイメージをランナーのローカル Docker デーモンにロードします。

## レイヤーキャッシュにどれだけの価値があるか: 実例

実測のベンチマークではなく、説明用の数字です。キャッシュなしで約 8 分かかるマルチステージの Node.js イメージを考えてみましょう: ベースイメージ、システムパッケージ、依存関係のインストール、コンパイル、アセンブルという構成です。レイヤーキャッシュがあれば、ソースのみの変更は最後のレイヤーだけを無効化します。それより上のすべてはレジストリキャッシュからプルされ、再ビルドは **1 分から 2 分の範囲** に収まります。依存関係のステージに触れるコミットはより多くのレイヤーを無効化してより多くを再ビルドするため、効果は、典型的な変更が Dockerfile のどれだけを手つかずのまま残すかに応じて変わります。デフォルトの `cache-mode: max` は、中間ステージのレイヤーもキャッシュされるため、ビルド後のより大きなキャッシュプッシュと引き換えに、まさにこうしたマルチステージ再ビルドでのヒット率を高めます。

## 入力と出力

| 入力 | デフォルト | 動作 |
| --- | --- | --- |
| `tags` | 必須 | ビルドされたイメージのタグ |
| `context` | `.` | ビルドコンテキストのパス |
| `dockerfile` | `Dockerfile` | Dockerfile へのパス |
| `push` | `false` | ビルドされたイメージをプッシュする |
| `build-args` | なし | ビルド引数。シークレットを含む可能性があるため、値はログでマスクされます |
| `target` | なし | マルチステージビルドのターゲットステージ |
| `platforms` | なし | ビルドのターゲットプラットフォーム |
| `cache-mode` | `max` | キャッシュのスコープ: `min` または `max` (max はマルチステージの中間レイヤーを含むすべてのレイヤーをキャッシュします) |
| `cache-tag` | `cache` | レイヤーキャッシュに使われるレジストリタグ |
| `extra-cache-from` / `extra-cache-to` | なし | ビルドに渡される追加のキャッシュソースおよびキャッシュ先 |

| 出力 | 意味 |
| --- | --- |
| `cache-configured` | ビルドでレジストリレイヤーキャッシュが有効だった場合は `true`、それ以外は `false` |
| `image-digest` | ビルドされたイメージのダイジェスト |

## どのランナーでも安全

- **Latchkey 以外のランナー** (たとえば GitHub ホストランナー) では、action はキャッシュレジストリが利用できないことを検出し、キャッシュフラグなしで通常どおりビルドします。1 つのワークフローファイルがランナーの種類をまたいでポータブルなまま保たれます。
- **リポジトリの最初のビルド**ではキャッシュは空です。その最初の実行でキャッシュ付きビルドが失敗した場合、action は自動的にキャッシュなしで再試行します。最初の実行がキャッシュのせいで壊れることはありません。
- **build-arg の値はログでマスクされる**ため、ビルド引数として渡されたシークレットがジョブ出力に漏れることはありません。
- キャッシュは**組織ごとに分離**されます。

> ****
> これを、ベースイメージを事前にプルする [カスタム AI Scan ランナー](/documentation/custom-runners) と組み合わせると、イメージビルドはプルと変更されていないレイヤーの両方をスキップします。

### 使い捨てランナーで Docker のレイヤーキャッシュはどう機能しますか?

`latchkey-dev/docker-cache-action@v1` が `docker buildx build` をレジストリ基盤のレイヤーキャッシュでラップするため、レイヤーはマシンではなくレジストリに保持されます。各シングルユースランナーは、変更で無効化されなかったレイヤーを取得し、無効化された分だけを再ビルドします。

### レジストリや認証情報の設定は必要ですか?

不要です。キャッシュ用レジストリ、その認証情報、権限は Organization ごとに事前構成されているため、設定なしで動作します。作成するものも追加する Secret もありません。

### Latchkey 以外のランナーでも動作しますか?

はい。Latchkey のキャッシュレジストリが利用できないランナーでは、それを検出してキャッシュフラグなしの通常の `docker buildx build` を実行します。複数のランナー種別で共有するワークフローでも分岐は不要です。

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
