Docker Buildx Bake を使用して複雑なイメージ ビルド パイプラインを作成する方法
公開: 2022-08-10 docker buildx
コマンド グループは、BuildKit を使用して高度なイメージ ビルド機能を公開します。 ベイク ビルドは、自動ビルド パイプラインを定義するために使用できる高レベルの機能です。 1 回のビルド操作で複数のイメージを生成できます。
ベイクされたワークフローは、イメージのさまざまなバリエーションを公開したり、リンクされた複数のプロジェクトを並行してビルドしたりする場合に役立ちます。 この記事では、 docker buildx bake
の主な機能と、それらを使用して複雑なビルドを合理化する方法について説明します。
入門
docker buildx bake
コマンドは、それぞれがコンテナー イメージを生成する複数のビルド「ターゲット」を実行します。 パフォーマンスを最大化するために、ターゲットは可能な限り並行して実行されます。 ターゲットは、先行するパイプラインを直接参照して、順次パイプラインを作成することもできます。
ビルド ターゲットは、既存の Docker Compose ファイルを含むいくつかの異なるメカニズムを使用して定義できます。 Buildx は、ファイルで識別されたすべてのイメージを自動的にビルドします。
JSON または HCL ファイルでビルド ターゲットをリストすると、より高度な機能が公開されます。 これらは、ビルドをカスタマイズするための変数、関数、および値の補間をサポートしています。
buildx bake
コマンドは、次のファイルを順番に探します。
-
docker-compose.yml
-
docker-compose.yaml
-
docker-bake.json
-
docker-bake.override.json
-
docker-bake.hcl
-
docker-bake.override.hcl
-f
コマンド フラグを使用して別のファイルを指定できます。
ビルド ターゲット
ビルド ターゲットは、ビルドに関連するすべての構成をカプセル化します。 次のような詳細が含まれます。
- ビルドする Dockerfile へのパス
- コンテキスト パスを構築し、Dockerfile 内で利用可能なコンテンツを定義する
- 出力画像に付けるタグとラベル
- 画像を生成するプラットフォーム。
サポートされている構成フィールドの完全なリストは、ドキュメントで入手できます。 以前は、これらの設定をコマンドライン フラグとしてdocker buildx build
(または通常の docker docker build
) に指定していたため、毎回正しい値を覚えておく必要がありました。 buildx bake
を使用すると、バージョン管理されたベイク ファイルで定義することにより、同じ値を確実に使用できます。
単一のビルド ターゲットを定義するdocker-bake.hcl
コマンドの簡単な例を次に示します。
target "default" { dockerfile = "app/Dockerfile" contexts = { app = "app/src" shared = "shared-components/src" } tags = ["my-app:latest", "docker.io/my-org/my-app:latest"] }
このベイク ファイルでdocker buildx bake
を実行すると、作業ディレクトリからapp/Dockerfile
Dockerfile が読み込まれます。 ビルド コンテキストとしてapp/src
およびshared-components/src
ディレクトリにアクセスできます。 生成された画像には 2 つのタグが割り当てられます。
docker buildx bake
を実行すると、 default
のターゲットが自動的にビルドされます。 オンデマンドで構築できる名前付きターゲットを定義することもできます。
target "app" { // ... }
$ docker buildx bake app
複数のターゲットの使用
ベイク ファイル内で新しいターゲットとして定義することにより、別のイメージを同時にビルドできます。
group "default" { targets = ["app", "api"] } target "app" { dockerfile = "app/Dockerfile" contexts = { app = "app/src" shared = "shared-components/src" } tags = ["my-app:latest", "docker.io/my-org/my-app:latest"] } target "api" { dockerfile = "api/Dockerfile" contexts = { src = "api/src" } tags = ["my-api:latest", "docker.io/my-org/my-api:latest"] }
これらのイメージは、グループにネストされているため、同時に構築できます。 default
グループが自動的に選択されるため、 docker buildx bake
コマンドを実行するたびに、 api
イメージとapp
イメージが並行してビルドされます。 上記の名前付きターゲットの例と同様に、名前付きグループを使用できます。
ビルド ターゲットの継承
ビルド ターゲットは相互に継承して構成を再利用できます。 これが役立つシナリオの 1 つは、さまざまな環境に合わせてカスタマイズする必要があるイメージに関するものです。 開発用のイメージ バリアントに追加の構成ファイルを追加することをお勧めします。 このモデルを示すdocker-bake.hcl
を次に示します。
group "default" { targets = ["backend", "backend-dev"] } target "backend" { dockerfile = "backend/Dockerfile" contexts = { src = "api/src" config = "api/config" } tags = ["backend:latest"] } target "backend-dev" { inherits = ["backend"] contexts = { config = "api/config-dev" } tags = ["backend:dev"] }
backend-dev
ターゲットは、 backend
ターゲットのすべてのプロパティを継承しますが、 config
コンテキストをオーバーライドし、別のタグを適用します。

--print
フラグを指定してbake
コマンドを実行すると、マージされたファイル構造をプレビューできます。
$ docker buildx bake --print ... "backend-dev": { "context": ".", "contexts": { "config": "api/config-dev", "src": "api/src" }, "dockerfile": "backend/Dockerfile", "tags": [ "backend:dev" ] } ...
以前のターゲットをベース イメージとして使用する
以前のターゲットによって作成されたイメージを独自のベースとして使用するビルド ターゲットが必要になる場合があります。 これは、Dockerfile が相互に依存しているが、おそらく異なるプロジェクトに存在するためにマージできない場合に使用できるマルチステージ ビルドの代替手段です。
group "default" { targets = ["org-base-image", "api"] } target "org-base-image" { dockerfile = "docker-base/Dockerfile" tags = ["org-base-image:latest"] } target "api" { dockerfile = "api/Dockerfile" contexts = { base = "target:org-base-image" } tags = ["api:latest"] }
この例では、最初にorg-base-image
ターゲットを構築します。 これには、組織のコンテナー化されたワークロードに共通するいくつかのユーティリティが含まれる場合があります。 api
ターゲットは、 base
ビルド コンテキストとしてアクセス可能なorg-base-image
ターゲットからの出力を使用してビルドされます。 API Dockerfile は、基本イメージ内のコンテンツを参照できるようになりました。
COPY --from=base /utilities/example /usr/bin/example-utility
これは、個別の Dockerfile を維持しながら、イメージ間の依存関係リンクを作成できる強力なパターンです。
ビルド時のターゲットのプロパティのオーバーライド
docker buildx bake
コマンドを使用すると、ビルドを実行するときにターゲットのプロパティをオーバーライドできます。
$ docker buildx bake --set api.dockerfile="api/Dockerfile-dev"
この例では、 api
ターゲットの Dockerfile を変更します。 *
ワイルドカードは、変更するターゲットを識別するときにサポートされています。 *
単独ですべてのターゲットを選択し、 api*
はapi
で始まるすべてのターゲットを変更します。
変数の設定
HCL ファイルは、ビルド ターゲットで参照できる変数を定義できます。 variable
ブロックを使用してそれらを設定します。
variable "TAG" { default = "latest" } group "default" { targets = ["app"] } target "app" { dockerfile = "src/Dockerfile" tags = ["my-app:${TAG}"] }
この構成でdocker buildx bake
を実行すると、 app
のターゲットがmy-app:latest
としてタグ付けされます。 コマンドを実行する前に環境変数を設定することで、 TAG
変数の値を変更できます。
$ TAG=v1 docker buildx bake
HCL 言語のすべての変数補間および比較機能を使用して、ビルド ターゲットを再利用可能にすることができます。 値を解析および変換するための関数も利用できます。
概要
Baked Buildx ビルドを使用すると、イメージ ビルド構成をファイルで定義された「ターゲット」としてカプセル化できます。 buildx bake
を実行すると、参照されているすべてのターゲットのイメージが並行してビルドされます。
ターゲットは相互に継承および依存できます。 変数と関数を使用して、非常に複雑で構成可能なビルド パイプラインを作成することもできます。
docker buildx bake
コマンドは、すべてのワークフローで必要なわけではない高レベルの操作です。 プロジェクト間の依存関係のない単純なイメージを作成する場合は、これを使用する必要はありません。 docker compose build
を使用することは、ビルド構成をdocker-compose.yml
ファイルに保持するほとんどのユース ケースでより優れた代替手段です。 異なる変数、プラットフォーム、ビルド コンテキスト、および構成オーバーライドを使用して同時に多くのイメージをビルドする場合は、ベイク ビルドへの切り替えを検討する必要があります。