2
1

docker buildを--cache-to/--cache-fromで高速化したかったが、docker-containerが必要になるようだ

Last updated at Posted at 2024-07-16

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=localtype=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 ...しておいてくれるので便利です。

https://github.com/docker/setup-buildx-action

作成したビルダーの情報を確認します:

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」と出ていてキャッシュが効いているのがわかります。

注意点

  1. --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ビルドプロセスにこの最適化テクニックを取り入れてみてください。

参考資料

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1