速く、もっと速く!Docker Build Cloudでイメージビルド時間を短縮する

2024/1/23に Docker Build Cloudが発表されました

www.docker.com

早速Docker Build Cloudを試してみました

Docker Build Cloudとは

サイト: https://www.docker.com/ja-jp/products/build-cloud/
ドキュメント: https://docs.docker.com/build/cloud/

イメージビルドをDocker社のCloud環境で行える機能です。 これによりどのようなメリットがあるかというと

  • イメージビルドキャッシュの共有
    • ローカルでイメージビルドするとき、もし他のユーザがビルド済みであればそのキャッシュを使うことができビルド時間が短縮できる
    • CI環境では毎回サーバーが違うため--mount=type=cacheが効かないがDocker Build Cloudであれば効く(!!)
    • ビルドキャッシュが存在するため--cache-fromのようにregistry cacheを使わなくてもよい。通常registry cacheを使うとかなりビルドが速くなるがregistry cache自体をpullする時間, pullしたイメージをextractする時間に地味に時間がかかるがそれがなくなる。
  • マルチアーキテクチャビルドが可能
  • CIツールとのシームレスな統合
    • ローカルのDockerやDocker Compose、GitHub ActionsやCircle CIなどのCIサービスと簡単に統合ができる

デメリットは、

  • Docker Build Cloudでビルドしたイメージをpullする時間がかかる
    • ただ変更があったimage layerだけがpullされるのでpullされるimage layerサイズが小さい場合はすぐ終わる
    • 2024/02/03現在 US Eastリージョンしかないため、Asiaからpullすると非常に時間がかかる。今後EuropeやAsiaリージョンのサポート予定
  • ビルドコンテキストをDocker Build Cloudに転送する時間がかかるケースがある
    • .dockerignoreを適切に設定していればビルドコンテキストサイズはそれほど大きくならないはずですが、何かしらの理由で大きなサイズの場合転送時間がネックになる可能性はあります。
  • planに含まれているビルド時間を超えてビルドしたい場合はビルド時間購入料金がかかる

料金に関して

無料PlanのDocker Personalだと 無料ビルド時間は 50分/月 です。かなり少ないですね。 Docker Teamに入っていれば 400分/月 のビルド時間が付与されますが、これは組織アカウント単位であり、ユーザ数あたりではないので注意。 このように無料付与枠がかなり少ないので本格的にDocker Build Cloudを使用する場合は Docker Build Cloud Team Planに入る必要があります。 年間払いだと $5/ユーザー/月、 月払いだと $6/ユーザー/月。 付与されるビルド時間は 200分/ユーザー/月 です。 これでも足りない場合はビルド時間を追加購入ことができます。

10,000分購入しても$500なのでかなり安い印象。

ちなみに、Docker Personal Planの無料枠の50minを使い切るとビルド時に

ERROR: failed to solve: FailedPrecondition: build cannot proceed build minutes limit of 50 reached

というエラーがでました。

使い方

https://build.docker.com/ にアクセスし、自分のprofileを選択します。

するとこういう画面がでるのでCreate new cloud builderからcloud builderを作成します。(この画面ではすでにmy-builderというcloud builderを作成済み)

作成したcloud builderをクリックすると、以下のような画面になります。

あとはSetup instructionsに表示される内容に沿って進めば簡単にDocker Build Cloudが使用できます。

実際速くなるのか?

イメージサイズが680MBになるDockerfileを使って試してみました。

ローカルでの使用

ローカルでのイメージビルドにDocker Build Cloudを使うメリットの一つはビルドキャッシュを共有出来る点です。
チームで開発をしている場合、フルビルドする場合イメージビルドに時間がかかります。 ビルドキャッシュを共有できれば他の人がすでにビルドした結果をpullすればよくなります。かなりイメージビルドが速くなりそうですよね。 しかし試してみると、Docker Build Cloudでビルドされたイメージをローカルにpullするのに長い時間がかかりました。 680MBのイメージをまるまるpullするのに6分くらい。更新されたimage layerだけをpullする場合でも330MBのサイズで190sくらい。更新されたimage layerのサイズが小さければ(1MB以下)なら数秒で終わりました。
これはDocker Build Cloudが2024/02/03現在、US Eastリージョンしかないため転送速度に時間がかかっているものと思われます。今後EuropeやAsiaリージョンのサポート予定だそうです。 Asiaリージョンのサポートがされてローカルでのpullが速くなればローカルでのDocker Build Cloudの使用も現実的になってくるかと思います。

CI上での使用

今回はCircleCIで試しました。
CircleCIはサーバーがUSリージョンにあるため、Docker Build Cloudでビルドしたイメージのpullにそれほど時間がかからないと見込んだからです。(GitHub Actionsは未調査)

CI上でのイメージビルドにDocker Build Cloudを使うメリットの一つはローカルでの使用と同様にビルドキャッシュを共有出来る点ですが、ポイントがローカルとは若干異なります。

  • Docker Build Cloudサーバーにビルドキャッシュ存在するため--cache-from, --cache-toのregistry cacheを使用しなくてよい。これによりregistry cacheイメージをpull&pushする時間, pullしたimageをextractする時間を削減できる
  • --mount=type=cacheが効く
    • たとえregistry cacheを使っていたとしてもアプリケーションで使うパッケージを更新した場合、ビルド時間がかかっていました。--mount=type=cacheを使うと追加/変更されたパッケージのみインストールすればよくなるためビルドが速くなりますが、CIでは毎回サーバーが異なるため--mount=type=cacheが使えないという課題がありました。Docker Build Cloudではビルドキャッシュが使えるため--mount=type=cacheが効きます。これによりアプリケーションで使うパッケージ更新時のイメージビルドが速くなります。

またもう一つのメリットはCIのサーバースペックを下げられる点です。イメージビルドを高速に行うにはサーバースペックが要求されるため、例えばCircleCIではresource classで大きめのclassを指定していた人も多いかと思います。Docker Build Cloudを使うとDocker Build CloudのサーバーはDocker Build Cloud Team Planの場合16 vCPU、32GB RAMのサーバーが割り当てられます。これによりCI側のサーバースペックを下げることができコスト削減ができる可能性があります。

さてローカルではDocker Build Cloudでビルドしたイメージのpullに時間がかかっていましたが、CircleCI上では680MBのイメージをまるまるpullするのに約20s、更新されたimage layerだけをpullする場合でも330MBのサイズで約10sでした。非常に速いですね。18倍も速いです。ただこれはDocker Build CloudのサーバーがAWS上にあり転送処理がAWSネットワーク内ですんでいるためかもしれません。
また--mount=type=cacheの指定も効いており、パッケージの更新処理も非常に速いです。registry cacheも必要ないためシンプルになります。

キャッシュサイズ

注意する点があるとすればビルドキャッシュサイズになります。
Docker Build Cloudではビルドキャッシュが保存されるわけですが、Docker Build Cloud Team Planの場合最大で200GiBになります。もし数多くのイメージをビルドする場合キャッシュ上限に達してしまう可能性があります。 なおキャッシュ上限に達すると、古いキャッシュは自動的に削除されます。
See: How do I manage the build cache with Docker Build Cloud?

FAQ

https://docs.docker.com/build/cloud/faq

まとめ

自分もそうですが、CI上でのイメージビルド高速化に苦労している人は少なくないと思います。ビルドキャッシュさえ存在すれば細かいことを考えずにすむのになと…よく思っていました。 Docker Build Cloudを使えば手軽かつ安価にイメージビルドの高速化ができそうです。 Productionで使われているイメージビルド処理が速くなるかは実際に試してみないと分からない部分もあるので仕事で検証をしていきたいと思います。