Dockerを使用した開発やCI/CDパイプラインでは、ビルド時間の短縮が重要な課題となります。本記事では、docker buildx
コマンドの--cache-to
および--cache-from
オプションを使用して、ビルドプロセスを高速化する方法を詳しく紹介します。
キャッシュオプションの概要
--cache-to
と--cache-from
オプションは、Dockerのビルドキャッシュを外部に保存し、再利用するための機能です。これらのオプションは、特にCI/CDパイプラインでの利用が有効で、異なるマシンや環境間でキャッシュを共有することでビルド時間を大幅に短縮できます。
実践:キャッシュオプションの使用
1. デフォルトドライバーでの試行
まず、デフォルトのdocker
ドライバーで--cache-to
オプションを試してみましょう。
docker buildx build -t test --cache-to type=local,dest=/tmp/foo,mode=max .
このコマンドを実行すると、次のようなエラーが発生します:
ERROR: Cache export is not supported for the docker driver.
Switch to a different driver, or turn on the containerd image store, and try again.
Learn more at https://docs.docker.com/go/build-cache-backends/
このエラーは、デフォルトのdocker
ドライバーがキャッシュエクスポートをサポートしていないことを示しています。
現在のドライバーの情報を確認してみましょう:
docker buildx inspect
docker buildx inspect の出力結果(クリックして展開)
Name: default
Driver: docker
Last Activity: 2024-07-16 04:12:23 +0000 UTC
Nodes:
Name: default
Endpoint: default
Status: running
BuildKit version: v0.13.2
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/386
Labels:
org.mobyproject.buildkit.worker.moby.host-gateway-ip: 172.17.0.1
GC Policy rule#0:
All: false
Filters: type==source.local,type==exec.cachemount,type==source.git.checkout
Keep Duration: 48h0m0s
Keep Bytes: 4.145GiB
GC Policy rule#1:
All: false
Keep Duration: 1440h0m0s
Keep Bytes: 30GiB
GC Policy rule#2:
All: false
Keep Bytes: 30GiB
GC Policy rule#3:
All: true
Keep Bytes: 30GiB
dockerドライバーはDocker組み込みのシンプルなドライバーらしく、試したかぎり--cache-to
オプションのうちtype=local
やtype=registry
などは使えないようです。
2. docker-containerドライバーの使用
キャッシュのインポート・エクスポートを行うには、docker-container
ドライバーを使用する必要があります。
docker buildx create --name docker-container --driver docker-container --bootstrap --use
このコマンドで使用しているオプションの説明:
-
--name docker-container
: 新しく作成するビルダーインスタンスに名前を付けます。ここでは "docker-container" という名前を使用しています。 -
--driver docker-container
: ビルダーインスタンスに使用するドライバーを指定します。ここでは docker-container ドライバーを使用します。 -
--bootstrap
: ビルダーインスタンスを作成後、すぐに初期化します。これにより、ビルダーがすぐに使用可能な状態になります。 -
--use
: 新しく作成したビルダーインスタンスをデフォルトのビルダーとして設定します。これにより、以降のdocker buildx
コマンドでこのビルダーが使用されます。
ちなみに、GitHub Actionsでは、@docker/setup-buildx-action
を使えば、これがdocker buildx create ...
しておいてくれるので便利です。
作成したビルダーの情報を確認します:
docker buildx inspect
docker-containerドライバーの詳細情報(クリックして展開)
Name: docker-container
Driver: docker-container
Last Activity: 2024-07-16 04:18:00 +0000 UTC
Nodes:
Name: docker-container0
Endpoint: unix:///var/run/docker.sock
Status: running
BuildKit daemon flags: --allow-insecure-entitlement=network.host
BuildKit version: v0.14.1
Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/386
Labels:
org.mobyproject.buildkit.worker.executor: oci
org.mobyproject.buildkit.worker.hostname: 8eb0e95840a7
org.mobyproject.buildkit.worker.network: host
org.mobyproject.buildkit.worker.oci.process-mode: sandbox
org.mobyproject.buildkit.worker.selinux.enabled: false
org.mobyproject.buildkit.worker.snapshotter: overlayfs
GC Policy rule#0:
All: false
Filters: type==source.local,type==exec.cachemount,type==source.git.checkout
Keep Duration: 48h0m0s
Keep Bytes: 488.3MiB
GC Policy rule#1:
All: false
Keep Duration: 1440h0m0s
Keep Bytes: 16.76GiB
GC Policy rule#2:
All: false
Keep Bytes: 16.76GiB
GC Policy rule#3:
All: true
Keep Bytes: 16.76GiB
3. キャッシュを使用したビルド
新しいドライバーで--cache-to
オプションを使用してビルドします:
docker buildx build -t test --cache-to type=local,dest=/tmp/foo,mode=max .
ビルドログ(クリックして展開)
TODO: ログを記入
ビルドが成功し、キャッシュが/tmp/foo
ディレクトリにエクスポートされました。
エクスポートされたキャッシュの構造は以下のようになっています:
/tmp/foo
├── blobs
│ └── sha256
│ ├── 4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1
│ ├── 9c704ecd0c694c4cbdd85e589ac8d1fc3fd8f890b7f3731769a5b169eb495809
│ ├── 9e01090d6864bc14898fc02d68dfbc80442f934fbffa163f0fb29e8d24175f25
│ └── f5de93f62cd6110aaf32524087c96664340c9841e2980371cf1479d1ec6be2b6
├── index.json
├── ingest
└── oci-layout
4. キャッシュを利用したビルド
エクスポートしたキャッシュを使用してビルドを行います。まず、既存のビルドキャッシュをクリアします。
docker buildx prune
次に、--cache-from
オプションを使用して、先ほどエクスポートしたキャッシュを利用しビルドします。
docker buildx build -t test \
--cache-to type=local,dest=/tmp/foo,mode=max \
--cache-from type=local,src=/tmp/foo .
キャッシュを利用したビルドログ(クリックして展開)
[+] Building 2.2s (7/7) FINISHED docker-container:docker-container
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 89B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:latest 1.3s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> importing cache manifest from local:7675087045324269413 0.0s
=> => inferred cache manifest type: application/vnd.oci.image.index.v1+json 0.0s
=> [1/2] FROM docker.io/library/ubuntu:latest@sha256:2e863c44b718727c860746568e1d54afd13b2fa71b160f5cd9058fc436217b30 0.0s
=> => resolve docker.io/library/ubuntu:latest@sha256:2e863c44b718727c860746568e1d54afd13b2fa71b160f5cd9058fc436217b30 0.0s
=> CACHED [2/2] RUN sleep 3 0.8s
=> => sha256:9c704ecd0c694c4cbdd85e589ac8d1fc3fd8f890b7f3731769a5b169eb495809 29.71MB / 29.71MB 0.3s
=> => extracting sha256:9c704ecd0c694c4cbdd85e589ac8d1fc3fd8f890b7f3731769a5b169eb495809 0.4s
=> => sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 32B / 32B 0.0s
=> => extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 0.0s
=> exporting cache to client directory 0.0s
=> => preparing build cache for export 0.0s
=> => writing layer sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 0.0s
=> => writing layer sha256:9c704ecd0c694c4cbdd85e589ac8d1fc3fd8f890b7f3731769a5b169eb495809 0.0s
=> => writing config sha256:8adbdd5a906d7945681aa5217f9289d3768af56835a578a0a6bf2de2c03a85db 0.0s
=> => writing cache manifest sha256:adde5cd70236d07d0a4c14ba61d40b18b447727baf6e0c694f60dd4558d90de2
ログを見るとコマンドに「CACHED」と出ていてキャッシュが効いているのがわかります。
注意点
-
--load
オプション:
ビルド結果をDockerイメージとして保存する場合は、--load
オプションを追加します。docker buildx build -t test \ --cache-to type=local,dest=/tmp/foo,mode=max \ --cache-from type=local,src=/tmp/foo \ --load .
まとめ
docker buildx
の--cache-to
と--cache-from
オプションを活用することで、Dockerビルドのパフォーマンスを大幅に向上させることができます。特にCI/CD環境での利用に適しており、ビルド時間の短縮とリソースの効率的な使用につながります。
ぜひ、あなたのDockerビルドプロセスにこの最適化テクニックを取り入れてみてください。
参考資料