Docker Buildx Bake を使用して複雑なイメージ ビルド パイプラインを作成する方法

公開: 2022-08-10

Docker ロゴを示すグラフィック

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ファイルに保持するほとんどのユース ケースでより優れた代替手段です。 異なる変数、プラットフォーム、ビルド コンテキスト、および構成オーバーライドを使用して同時に多くのイメージをビルドする場合は、ベイク ビルドへの切り替えを検討する必要があります。