複数のDockerfileやビルドスクリプトを長年運用してきた業務システムでは、ビルド設定が肥大化しがちです。マイクロサービス構成でイメージが10個を超える、環境ごとにビルド引数が違う、CIとローカルでビルドコマンドが微妙に食い違う。こうした悩みを抱えるバックエンドエンジニアやSRE担当者に向けて、Docker Bake(ビルド設定を宣言的にまとめる仕組み)を整理します。
200行を超えるbashスクリプトでイメージのビルド・タグ付け・プッシュを制御しているプロジェクトは、珍しくありません。Docker Bakeは、そうしたスクリプトが担ってきた役割を、HCL(HashiCorp Configuration Language、Terraformでも使われる設定記述言語)やJSONの宣言的ファイルに置き換える仕組みです。
Docker Bakeとは何か、なぜ今注目されるのか
Docker Bakeは、複数のDockerイメージのビルドを1つの設定ファイルで定義し、docker buildx bakeコマンドで一括実行する機能です。
Buildxのサブコマンドとして提供されており、Docker Desktopや最近のDocker Engineには標準で同梱されています。特別なプラグインを追加インストールする必要はありません。
注目される理由は単純です。マイクロサービスアーキテクチャの普及で、1リポジトリに複数のDockerfileが並ぶ構成が一般化しました。認証サービス、APIゲートウェイ、バッチ処理、フロントエンド配信用と、役割ごとにイメージを分けるチームは多いはずです。
それぞれを個別にdocker buildしていくと、タグ付けのルール、ビルド引数、キャッシュ設定がバラバラになりやすくなります。結果として、誰かが「このイメージだけタグの付け方が違う」と気づいて調査する、という保守コストが発生します。
BuildKit・Buildx・Bakeの関係を整理する
Docker Bakeを理解するには、3つの階層を区別する必要があります。名前が似ているため混同されがちですが、それぞれ役割が異なります。
一番下の層がBuildKitです。Dockerfileを解析し、可能な部分を並列実行し、キャッシュやマルチプラットフォームビルド、シークレットのマウントなどを処理する、実際のビルドエンジンです。Docker Engine 23以降では標準のビルドエンジンとして採用されています。
中間層がBuildxです。BuildKitの機能を扱いやすいCLIとして提供するDocker公式プラグインで、docker buildx buildコマンドの実体です。ローカル・リモート・コンテナ駆動など、複数のビルダー(BuildKitインスタンス)を切り替える管理機能も持っています。
一番上の層がBakeです。Buildxのサブコマンドとして、複数のビルド設定をHCLファイルにまとめ、宣言的に一括実行します。イメージ間の依存関係やビルド引数の継承も表現できます。
つまりBakeは、bashスクリプトでdocker buildを何度も呼び出していた処理を、設定ファイル1つに集約する層だと捉えると分かりやすいはずです。
具体的なコマンドと挙動
実際のコマンドを見ると、Bakeの立ち位置がはっきりします。
# 変数定義ファイルとビルド設定を指定して実行
docker buildx bake -f vars.hcl -f docker-bake-app-and-infra.hcl
# ビルドしたイメージをレジストリにプッシュ
docker buildx bake -f vars.hcl -f docker-bake-app-and-infra.hcl --push
# 変数展開後の設定を確認(実行はしない)
docker buildx bake -f vars.hcl -f docker-bake-app-and-infra.hcl --print--printフラグは地味に見えて重要です。変数がどう展開され、最終的にどんなビルド設定が実行されるのかを、実際にビルドを走らせる前に確認できます。
CIパイプラインで「意図しないタグでプッシュされていた」というトラブルは、この--printを使ったドライラン的な確認で事前に防げるケースが多いはずです。
Bakeファイルは複数指定でき、-fオプションを重ねることでベース設定と環境固有の上書き設定を分離できます。lintやテスト専用のターゲットを別ファイルにする、継承(inheritance)で共通設定を親ターゲットにまとめる、といった構成も可能です。
既存のbashスクリプト・Composeとの違い
既存のビルド運用と比較すると、Bakeの価値がより明確になります。
bashスクリプトでのビルド管理は、自由度が高い反面、条件分岐やエラーハンドリングが個人の書き方に依存しがちです。担当者が変わるたびに読み解きが必要になる、というのはよくある保守上の悩みです。
Docker Composeも複数サービスのビルドを扱えますが、本来は「起動時の構成管理」が主目的です。ビルドオプションの表現力(ターゲット間の依存関係、マトリクス的なビルドバリエーションなど)ではBakeの方が細かく制御できます。
Bakeファイル自体はレジストリに依存しません。Docker Hub、Amazon ECR、Azure Container Registry、GitHub Container Registry、Google Cloud Artifact Registryのいずれでも、ターゲットのタグ設定を変えるだけで対応できます。マルチクラウド構成や、オンプレからクラウドへの移行期にあるチームでも、レジストリの切り替えコストを抑えられる設計です。
今日から確認できること
導入を検討する前に、まず自分の環境がBakeを使える状態かを確認します。
# Buildxのバージョンとbakeサブコマンドの有無を確認
docker buildx version
docker buildx bake --helpDocker Desktopの最近のバージョンであれば標準で使えますが、社内の共有ビルドサーバーやCIのDockerイメージが古いDocker Engineを使っている場合は、Buildxが同梱されていない可能性があります。Docker Engine 23以降かどうかをdocker versionで確認しておくと安心です。
既存プロジェクトが該当するかどうかは、以下の基準で判断できます。
- Dockerfileが3つ以上あり、ビルド用のbashスクリプトが100行を超えている
- 環境(dev/stg/prod)ごとにビルド引数やタグ規則を分岐させている
- CIとローカル開発でビルドコマンドの挙動がずれた経験がある
- lint用イメージ・テスト用イメージなど、アプリ本体以外のビルドも管理している
これらに複数当てはまる場合、Bake導入で得られる整理効果は大きいはずです。逆にDockerfileが1つしかない小規模なプロジェクトでは、Bakeを導入するメリットは限定的です。単純なdocker buildのままで十分なケースも多いでしょう。
移行を進める場合は、既存のbashスクリプトを一度に置き換えるのではなく、ビルド対象の一部からHCLファイル化していくのが現実的です。まずは--printで既存スクリプトと出力結果を突き合わせ、差分がないことを確認してから本番CIに組み込む、という段階的な進め方が事故を防ぎます。
まとめ
Docker Bakeは、BuildKitというビルドエンジン、Buildxというフロントエンドの上に乗る、宣言的なビルド設定管理の層です。
複数Dockerfile・複雑なbashスクリプトを抱えるプロジェクトほど、HCLファイルへの集約による見通しの改善効果は大きくなります。
導入判断は、Dockerfileの数・ビルドスクリプトの行数・環境別のビルド差分の有無という具体的な基準で確認できます。
まずはdocker buildx bake --helpで手元の環境がBakeに対応しているか確認し、既存スクリプトの一部を--printで試すところから始めてみてください。