🤖

🤖

:gijutsu_burogu:

CI上でのマルチステージビルドにおけるキャッシュ活用の銀の弾丸を見つけたかもしれない(Buildx, BuildKit)

銀の弾丸

以下でキャッシュ活用、ビルド、Push をよしなに行ってくれます。

$ docker login -u $DOCKERHUB_USER -p $DOCKERHUB_PASS # Docker Hub や ECR にログイン
$ export DOCKER_CLI_EXPERIMENTAL=enabled # Buildxを有効にする
$ docker buildx create --use --driver docker-container # ビルダーを作成(これがないと--pushオプションが使えない)
$ docker buildx build \
    --tag $IMAGE:latest \ # タグを付与
    --cache-from type=registry,ref=$IMAGE:cache \ # キャッシュのPull先を指定(レジストリを指定)
    --cache-to type=registry,ref=$IMAGE:cache,mode=max \ # キャッシュのPush先を指定(レジストリを指定)、mode=maxにより中間イメージのキャッシュも含める
    --push \ # 最終イメージのPushも行う
    .

はじめに

これまで、CI でのマルチステージビルドのキャッシュ活用についてさまざまな記事を書いてきました。

キャッシュのためにDockerビルドで中間イメージをタグ付けしレジストリにPushする - 🤖

GitHub Actionsを例にCI環境でのマルチステージビルドのキャッシュの活用について🐳 - 🤖

これらでは中間ステージのキャッシュに苦労しました。 各々のステージにタグを付与し各々のステージを Push していて、面倒くさいし可読性が低くなっていました。

Buildxのドキュメントを読む機会があり、簡単にマルチステージビルドでキャッシュを活用できるようでした。 この機能はDocker 19.03 から利用可能です。

github.com

Buildx とは

Docker Buildx は Docker コマンドを拡張する CLI プラグインであり、Moby BuildKit ビルダーツールキットにより提供される機能に完全対応するものです。 Docker ビルドと同様のユーザー操作を提供し、さらにスコープ化されたビルダーインスタンス、複数ノードへの同時ビルドなど、数多くの新機能を提供します。

元々、Docker には BuildKit の一部の機能は含まれていました。 しかし、Buildx を利用することで、BuildKit の全ての機能を利用できます。 Buildx がbuildkitdという BuildKit デーモンをコンテナで立ち上げてそこでビルドを行うことで実現しています。

Buildx なしで BuildKit を使おうとすると、--cache-fromオプションは利用できましたが--cache-toオプションは利用できませんでした。 Buildx を利用すると、--cache-to type=registry,ref=$IMAGE:cache,mode=maxと書くことで中間ステージのキャッシュも含めて外部レジストリに Push できます。

以下でキャッシュ活用、ビルド、Push をよしなに行ってくれます。

$ docker login -u $DOCKERHUB_USER -p $DOCKERHUB_PASS # Docker Hub や ECR にログイン
$ export DOCKER_CLI_EXPERIMENTAL=enabled # Buildxを有効にする
$ docker buildx create --use # ビルダーを作成(これがないと--pushオプションが使えない)
$ docker buildx build \
    --tag $IMAGE:latest \ # タグを付与
    --cache-from type=registry,ref=$IMAGE:cache \ # キャッシュのPull先を指定(レジストリを指定)
    --cache-to type=registry,ref=$IMAGE:cache,mode=max \ # キャッシュのPush先を指定(レジストリを指定)、mode=maxにより中間イメージのキャッシュも含める
    --push \ # 最終イメージのPushも行う
    .

実際に GitHub Actions で使用している例は以下のようになります。

github.com

GitHub Actions ではこれで Buildx を利用できましたが、 AWS CodeBuild では Buildx を使えませんでした。 以下のようにして、CLI プラグインを導入する必要がありました。

$ export DOCKER_BUILDKIT=1
$ docker build --platform=local -o . git://github.com/docker/buildx
$ mkdir -p ~/.docker/cli-plugins
$ mv buildx ~/.docker/cli-plugins/docker-buildx

この処理によるオーバーヘッドが大きいので、AWS CodeBuild では Buildx を使うのは微妙ですね。

github.com

CodeBuild のベースイメージに最初から Buildx 加えればいいのではと思いましたが、

Unfortunately, we won't be adding any experimental features.

と言われました。

参考

docs.docker.com

qiita.com

roy-n-roy.github.io