AWS CodeBuild + Docker Serverによるキャッシュ永続化の恩恵と運用の課題

この記事は TVer Advent Calendar 2025 5日目の記事です。

はじめに

こんにちは。TVerでDevOpsを担当している鈴木です。

TVerのバックエンドではECSを活用しており、アプリケーションの変更にはコンテナイメージのビルドが必須です。 開発組織の拡大に伴い、1日のビルド回数が増加したことで、デプロイ待ち時間が無視できない課題となってきました。

今回は、ビルド時間を短縮するためにCodeBuildの「Docker Server」機能によるキャッシュ永続化を試みた事例を紹介します。 結果としてビルド時間を約50%ほど高速化しましたが、運用上の課題により採用を見送った経緯までを共有します。

なぜDocker Serverの導入を検討したか

従来のCodeBuildでは以下の理由からビルドごとのキャッシュ効率が悪いという課題がありました。

  • 環境のリセット: ビルドごとにビルド用環境が破棄されるため、ローカルのDockerレイヤーキャッシュが残らない
  • ネットワークコスト: --cache-from でECRからプルするには転送に時間がかかる

上記課題をできるだけ少ない工数で解消するためにCodeBuildの「Docker Server」機能を試してみることにしました。

Docker Serverはコンテナイメージのビルドをリモートホストに集中化することでビルドを高速化でき、デプロイの待ち時間を短縮することができます。 AWS CDKを利用している場合、以下のようにCodeBuildの定義に dockerServer プロパティを数行追記するだけで有効化できます。

// CodeBuildプロジェクトの定義
const cfnProject = new CfnProject(stack, 'SampleProject', {
  // ...その他設定
  environment: {
    // type, image, computeType などの他の環境設定
    dockerServer: {
      computeType: codebuild.ComputeType.X_LARGE, // Docker Serverのインスタンスタイプを指定
    },
  }
});

Docker Serverの詳細の仕様やコンソールからの有効化手順については公式のドキュメントが分かりやすいのでこちらを参照ください。 aws.amazon.com

導入効果:49%の高速化を実現

Docker Serverを有効にしたところ、ビルド時間が4分 58秒 -> 2分 31秒と大幅に短縮されました。

変更頻度の低いベースイメージの取得や go mod download がキャッシュされるようになったことで、ビルド時間を49%削減できました。

直面した「安定性」の壁

速度面では期待以上の成果が出ましたが、運用を開始してからいくつかの課題に直面しました。 今回検証したビルドプロセスは、最大10並列でのコンテナ生成に加え、単一プロジェクトで複数環境のビルドを並行処理するため、極めてリソース負荷が高い特性を持っていました。

ビルドのタイミングによってはCodeBuildとDocker Server間の一時的な通信エラーと思われる以下のような事象が発生しビルドが失敗するようになりました。

ERROR: failed to run Build function: malformed header: missing HTTP content-type
ERROR: DeadlineExceeded: context deadline exceeded
ERROR: failed to receive status: rpc error: code = Unknown desc = malformed header: missing HTTP content-type

多くのエラーは一時的なものであり、リトライで解消することもありました。しかし、中には15分以上リトライしても同じエラーが解消されないケースも発生することもありました。 リトライが発生すれば、せっかくの高速化の恩恵は帳消しになりむしろ待ち時間は増えてしまいます。

健全な開発サイクルを維持するためには、ビルド速度の短縮だけでなく、「実行結果に対する信頼性」が不可欠です。 不安定な高速化は、結果として手戻りを生み、開発効率を下げてしまうためです。

また、根本原因の特定や監視が困難であることも、採用を見送る大きな要因となりました。

多数のビルドが並列実行される環境下では、Docker Server側のCPUやメモリリソースが逼迫している可能性を疑いました。 しかし、CodeBuildの管理コンソール上にはDocker Server固有のメトリクスが見当たらなかったため、AWSサポートへ問い合わせたところ「現時点ではDocker Serverの内部状況を確認できるメトリクスなどは提供されていない」との回答をいただきました。

上記からビルド時間の短縮とビルドの安定性の天秤にかけた結果、今回はDocker Serverの導入を見送ることとしました。

まとめ

今回検証したDocker Server機能についても、詳細なチューニングを行えば安定化の余地はあったかもしれません。 しかし、今回は「少ない工数で迅速に成果を出すこと」を重視したため、導入を見送る判断に至りました。

もちろん、手段はこれに限りません。 今後はDocker Build CloudなどのSaaS活用も含めより幅広い選択肢を検証していく予定です。

より良い開発者体験を提供するために、これからもインフラ改善に取り組んでいきたいと思います。