
こんにちは。株式会社スマートバンク SRE部の capytan です。スマートバンク 新春エンジニア駅伝 2026 の十四区目の走者として頑張って走ります。十三区目は nissyi さんの Agent Client Protocol 入門 -エディタとAIエージェント連携の仕組みを体験する- でした。
本記事は、ゆるSRE勉強会 #14 で発表したLTの内容をもとに加筆・修正したものです。
CI/CDパイプラインの高速化は、多くのチームが一度は取り組む課題ではないでしょうか。Pull Requestをマージしてから本番に反映されるまでの時間は、開発者体験に直結します。障害対応時に「修正はできたけど、デプロイに30分かかる……」という状況は、なかなかつらいものがあります。
本記事では、私たちがDockerビルドのキャッシュ戦略を見直すことで、デプロイ時間を50〜65%削減した取り組みについてご紹介します。特別なツールや大規模な構成変更は必要なく、既存のDockerとBuildKitの機能を活用するだけで実現できる内容です。
なぜデプロイ高速化に取り組んだのか
SRE本1の8章「リリースエンジニアリング」には、こんな一節があります。
8.2.2 高速性 リリースを頻繁に行うことで、バージョン間の変更を少なくするという哲学を支持しています。このアプローチによって、テストとトラブルシューティングが容易になります。
そして、リリース頻度を上げるためには、デプロイが速いことが前提条件です。デプロイに時間がかかると、開発者は自然とリリースを溜め込むようになり、結果として1回のリリースに含まれる変更が大きくなります。さらに、変更が大きいと問題の切り分けが難しくなり、障害対応も長引きます。2
当社でも、デプロイに26〜34分かかっている状態が常態化していました。
まずは現状把握
「デプロイを速くしたい」と思っていても、具体的な行動を起こさなければ何も変わりません。まずは現状を正確に把握することから始めました。
当社では Amazon Web Services の CodePipeline や CodeBuild 、CodeDeploy などのCodeシリーズを用いたデプロイシステムが組まれております。2年ほど前のものですが、当社のデプロイフローについて記載してあるブログ記事がございますので、こちらも合わせてご覧ください。
AWS CodeBuildの実行ログを確認してみると、以下のような内訳が見えてきました。
[Container] Phase Duration DOWNLOAD_SOURCE : 30s PRE_BUILD : 2m BUILD : 18m ← ここが長い POST_BUILD : 1m
BUILDフェーズが全体の大部分を占めています。このフェーズではDockerイメージのビルドを行っているのですが、詳細を見るとほぼ毎回フルビルドが走っていることがわかりました。
つまり、Dockerビルドのキャッシュが効いていなかったのです。
解決策1: Registry Cacheの導入
なぜローカルキャッシュでは不十分なのか
CI/CD環境では、ビルドごとに新しいインスタンスが起動することが一般的です。そのため、ローカルに保存されたDockerレイヤーキャッシュは次回のビルドでは利用できません。
この問題を解決するのがRegistry Cacheです。Docker Buildxを使用すると、ビルドキャッシュをコンテナレジストリ(Amazon ECRなど)に保存し、次回のビルドで再利用することが容易にできます。
実装方法
buildspec.ymlやCI設定で、以下のようにDocker Buildxを使用します。
# Docker Buildxでビルド(Registry Cache使用) docker buildx build \\ --cache-from type=registry,ref=your-registry/your-app:buildcache \\ --cache-to type=registry,ref=your-registry/your-app:buildcache,mode=max \\ -t your-registry/your-app:latest \\ --push \\ --provenance=false \\ .
ポイント: mode=maxの重要性
-cache-toオプションのmode=max も効くパターンがあると思います。
mode=min: 最終ステージのレイヤーのみキャッシュmode=max: すべての中間レイヤーをキャッシュ
マルチステージビルドを使用している場合、mode=maxを指定しないとビルダーステージのキャッシュが効きません。
解決策2: キャッシュマウントの活用
Registry Cacheに加えて、Dockerfile内でのキャッシュマウントも効果的でした。
キャッシュマウントとは
Docker公式ドキュメント3では、キャッシュマウントについて以下のように説明されています。
This persistent caching means that even if you need to rebuild a layer, you only download new or changed packages. Any unchanged packages are reused from the cache mount.
(日本語訳)レイヤーを再ビルドする必要がある場合であっても、新規または変更されたパッケージのみをダウンロードします。変更されていないパッケージはキャッシュマウントから再利用されます。
通常のレイヤーキャッシュでは、RUN 命令の内容が変わると、そのレイヤー以降はすべて再実行されます。一方、キャッシュマウントを使用すると、パッケージマネージャのキャッシュディレクトリをビルド間で共有でき、差分のみのダウンロードが可能になります。
実装例: パッケージマネージャのキャッシュ
# apt(Debian系)の場合
RUN --mount=type=cache,target=/var/cache/apt \\
--mount=type=cache,target=/var/lib/apt \\
apt-get update && apt-get install -y git jq
# dnf(Red Hat系)の場合
RUN --mount=type=cache,target=/var/cache/dnf \\
dnf -y install git jq procps
結果: 50〜65%の時間削減
これらの改善を適用した結果、以下のような効果が得られました。development環境の削減率が高いのはstaging、productionと若干デプロイ方法が異なるためです。
| 環境 | Before | After | 削減率 |
|---|---|---|---|
| development | 26-30分 | 9-10分 | 約65% |
| staging | 26-30分 | 14分 | 約50% |
| production | 26-30分 | 14分 | 約50% |
その他の改善
Docker Buildのキャッシュ戦略以外にも、いくつかの改善を並行して進めました。
共通ベースイメージの整備
当社では社内で使用するRubyやPythonなどのベースイメージを整備しています。これらの記述を整理することで、プロジェクトでのビルド時間を4〜6分短縮しました。共通で必要なパッケージをベースイメージに含めることで、プロジェクトごとのインストール時間を削減しています。
Blue/Greenデプロイの待機時間短縮
AWS CodeDeployのBlue/Greenデプロイにおける待機時間を見直しました。本番環境ではヘルスチェックの猶予時間を十分に取る必要がありますが、開発環境ではより短い設定で十分であるという割り切った形です。
横展開
効果が確認できた施策は社内の他のリポジトリにも展開しました。Dockerfileやbuildspec.ymlの書き方を統一する改善活動を進めて、多くのリポジトリで同様の改善を適用しています。
まとめ
本記事では、Docker Buildのキャッシュ戦略を見直すことでデプロイ時間を50〜65%削減した取り組みを紹介しました。デプロイ高速化は、直接的にはインフラの改善ですが、その効果は開発者体験の向上を通じてプロダクト全体に波及します。開発者がストレスなくリリースできる環境を整えることは、SREの重要な役割の一つだと考えています。
次の スマートバンク 新春エンジニア駅伝 2026 は、 nagasawa さんです!張り切っていこう。
参考リンク
- 本記事のもとになったLTスライド(Speaker Deck)
- Docker公式ドキュメント - Optimize build caching
- Docker Buildx - Build cache backends
- AWS CodeBuild - Docker layer caching
- Betsy Beyer 他著『SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム』オライリージャパン、2017年↩
- ここでいう「リリース」はユーザーに変更を提供開始すること、「デプロイ」は変更を本番環境に反映することを指します。例えば、デプロイ済みでもフィーチャーフラグや段階ロールアウトにより未リリースである場合などを念頭におきます。↩
- Docker公式ドキュメントは宝の山なので一読することをオススメします / Docker公式ドキュメント - Optimize build caching↩