青色に照らされたサーバーブレードが並ぶデータセンター
現場の実践

Docker Bakeとは何か Dockerfileが複数あるチームの整理術

目次を見る

複数の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 --help

Docker 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で試すところから始めてみてください。

参考

Docker Bake in Practice — Part 1: From Bash Scripts to Declarative Builds

この記事について: 本記事は AI を活用して作成し、forva AI 編集部が内容を確認・監修しています。

AI 駆動開発のご相談は forva AI へ。まずはお気軽にどうぞ。