AWS

AWS CodeBuild に追加された Docker サーバー機能の技術的メリットを探る

hosso

こんにちは、ほっそーです。

つい先日、 AWS CodeBuild に「Docker サーバー機能」という新機能の追加が発表されました!
この機能は、AWS CodeBuild を採用しているチームやプロジェクトにとって、大きな影響を与えるアップデートです。AWS 公式ブログでは「ビルド時間が 24 分 → 16 秒に短縮された」というベンチマークも紹介されており、その効果の本質は、単なるキャッシュ強化ではなく、ビルド環境の構造そのものが変わったことにあるようです。

なお、実際の設定方法や使い方については AWS 公式ブログに詳しく記載されていますので、導入をご検討の方は下記をご参照ください。

AWS CodeBuild の新しい Docker サーバー機能で CI/CD パイプラインを高速化

本記事では、従来のキャッシュ機能との違いや、Docker サーバー機能がもたらす技術的メリットについて考えてみました。

従来のAWS CodeBuildが持つキャッシュ機能について

Docker サーバー機能が登場する以前、CodeBuild では主に2つのキャッシュ手法が活用されていました。

ローカルキャッシュ(cache: local)

ビルド成果物や依存ファイルを S3 に保存しておき、次回ビルド時に復元する仕組みです。たとえば LOCAL_DOCKER_LAYER_CACHE を使えば、Docker レイヤーもキャッシュ対象にできます。適切に使えばビルド時間の短縮に役立ちますが、復元時には展開や整合性チェックが入るため、環境によっては効果が限定的になることもあります。

リザーブドキャパシティ

ビルド用の環境(インスタンス)を事前に確保しておくことで、起動待ち時間を短縮する機能です。ビルド処理そのものの速度には影響しませんが、特に高頻度でビルドを回すようなケースでは有効です。

これらの機能は、それぞれの用途や規模に応じて十分に活用できると思います。
今回の Docker サーバー機能は、そこに「状態を持ち越せる常駐環境」という新しい選択肢が加わった、という位置づけになります。

Docker サーバー機能は従来のCodeBuildと比べて何が嬉しいのか

今回のアップデートにより、Docker イメージのビルドがより高速かつ効率的になりました。
従来の CodeBuild との構造的な違いを、以下の図にまとめてみました。

では、技術的な視点で得られるメリットを考えてみます。

「常駐型 Docker デーモン」による状態の持続が可能になった。

従来の CodeBuild は、ステートレスな短命実行環境で動作するため、Docker イメージやレイヤーキャッシュはビルド終了とともに破棄されていました。その結果、毎ビルドで以下のような I/O 処理が発生していました。

  • Docker デーモンの初期化
  • イメージの Pull と展開
  • キャッシュの復元と整合性チェック

一方、Docker サーバー機能では、常駐する Docker デーモン(長命プロセス) がバックグラウンドで稼働しており、キャッシュは OS レベルで持続されます。
これにより、ビルド成果物や中間キャッシュの再利用が一瞬で可能となり、初期処理の大幅な削減が実現します。

ファイルキャッシュの実体がローカルボリュームに保持されるようになった

Docker のキャッシュ(特にレイヤーキャッシュや --mount=type=cache で使用される一時ボリューム)は、通常 ホストOS上の以下の階層に保存されます。

/var/lib/docker/overlay2/
  ├─ 各レイヤーの差分ファイル
  ├─ キャッシュマウント時の temp volume

従来の CodeBuild では、このファイルシステムはビルドごとに都度作成・破棄されており、たとえ ローカルキャッシュを用いてキャッシュを有効にしても、実際には S3 からの復元が必要でした。
そのため、ビルド時には以下の処理が毎回ネットワーク越しの I/O を伴って発生していました。

  • レイヤーデータの再展開
  • マウントポイントの作成
  • pullのレイヤーハッシュ確認

一方、Docker サーバー機能ではこれらのキャッシュがホスト上に永続的に保持されるため、以下のようなメリットが得られます。

  • キャッシュへの即時アクセス(ローカルI/O
  • Docker レイヤーの再展開が不要
  • RUN ステップ間のステートが維持され、差分ビルドがより効果的に機能

結果として、I/O 負荷や再構築のオーバーヘッドが大幅に削減され、ビルド時間の短縮につながります。

コンテナビルド時の「処理コスト」が劇的に短縮される

従来の CodeBuild では、Docker を使うには基本的に Docker in Docker (DinD) を用いる構成になります。これは、CodeBuild 上の一時コンテナの中で docker を起動し、そこからビルドを実行するという二重構造です。この構成には以下の欠点があります。

  • I/Oパスが長い(コンテナ内の /var/lib/docker → ネットワーク越しのECR/S3)
  • CPU/メモリ消費が高い(ビルドコンテナ+DinDの二重負荷
  • セキュリティリスクがある(Dockerソケットのマウント)

Docker サーバー機能では、CodeBuild 上のプロセスからリモートの常駐 Docker デーモンに対して build リクエストを投げる構成になります。
これにより、以下のような恩恵を受けられます

  • Docker Daemon の再起動が不要
  • 既存キャッシュや pull済みイメージをそのまま使える
  • 全ビルドで共通の build context を再利用できる

Docker サーバー機能は“いつまで残る”?起動・停止の仕組みについて

Docker サーバー機能では、通常のビルド環境とは別でCodeBuild プロジェクトごとに専用の Docker サーバーがプロビジョニングされます。
このサーバーの起動・停止に関するポイントは以下の通りです

  • ビルド中のみ起動し、終了後は自動で停止
  • 停止後も最大 1 か月間は保持され、再利用可能
  • キャッシュは OS レベルで維持され、S3 復元は不要
  • docker build はこの常駐サーバーにリモート実行される

これにより、Docker レイヤーキャッシュや buildx の成果物が維持され、次回以降のビルドを高速化できます。

参考: Docker image build server sample for CodeBuild

最後に

いかがだったでしょうか。
今回ご紹介した AWS CodeBuild の新しい「Docker サーバー機能」は、従来のキャッシュ機能やビルド環境とは根本的に異なるアプローチで、Docker イメージのビルドを高速化できる仕組みです。
特に、頻繁にビルドを実行するプロジェクトや、ビルド時間の短縮が求められるケースにおいて、大きな効果を発揮する機能だと感じました。
本記事が、CodeBuild の活用を見直すきっかけや、ビルドパイプライン改善の参考になれば幸いです。

AUTHOR
hosso
hosso
記事URLをコピーしました