So verwenden Sie Docker Buildx Bake zum Erstellen komplexer Image-Build-Pipelines

Veröffentlicht: 2022-08-10

Grafik mit dem Docker-Logo

Die docker buildx -Befehlsgruppe verwendet BuildKit, um erweiterte Image-Erstellungsfunktionen bereitzustellen. Gebackene Builds sind eine High-Level-Funktion, die zum Definieren automatisierter Build-Pipelines verwendet werden kann. Mit ihnen können Sie mehrere Images aus einem einzigen Build-Vorgang erstellen.

Gebackene Workflows sind hilfreich, wenn Sie verschiedene Varianten Ihrer Bilder veröffentlichen oder mehrere verknüpfte Projekte parallel erstellen möchten. In diesem Artikel behandeln wir die wichtigsten Funktionen von docker buildx bake und wie Sie sie verwenden können, um komplexe Builds zu rationalisieren.

Einstieg

Der docker buildx bake Befehl führt mehrere Build-„Ziele“ aus, die jeweils ein Container-Image erzeugen. Ziele werden nach Möglichkeit parallel ausgeführt, um die Leistung zu maximieren. Ziele können auch direkt auf Vorgänger verweisen, um sequentielle Pipelines zu erstellen.

Build-Ziele können mithilfe verschiedener Mechanismen definiert werden, einschließlich vorhandener Docker Compose-Dateien. Buildx erstellt automatisch alle in der Datei identifizierten Images.

Erweiterte Funktionen werden verfügbar gemacht, wenn Sie Build-Ziele in JSON- oder HCL-Dateien auflisten. Diese unterstützen Variablen, Funktionen und Wertinterpolation, um Ihre Builds anzupassen.

Der buildx bake Befehl sucht der Reihe nach nach den folgenden Dateien:

  • docker-compose.yml
  • docker-compose.yaml
  • docker-bake.json
  • docker-bake.override.json
  • docker-bake.hcl
  • docker-bake.override.hcl

Sie können mit dem Befehlsflag -f eine andere Datei angeben.

Ziele bauen

Build-Ziele kapseln die gesamte Konfiguration, die sich auf Ihren Build bezieht. Sie enthalten Details wie z

  • den Pfad zu der zu erstellenden Docker-Datei
  • Erstellen Sie Kontextpfade und definieren Sie den Inhalt, der in Ihrem Dockerfile verfügbar ist
  • Tags und Labels zum Anhängen an die Ausgabebilder
  • die Plattformen, für die Bilder produziert werden.

Eine vollständige Liste der unterstützten Konfigurationsfelder finden Sie in der Dokumentation. Zuvor haben Sie diese Einstellungen möglicherweise als Befehlszeilen-Flags an docker buildx build (oder sogar einfach docker build ) übergeben, sodass Sie sich jedes Mal die richtigen Werte merken müssen. Mit buildx bake können Sie zuverlässig die gleichen Werte verwenden, indem Sie sie in Ihrer versionierten gebackenen Datei definieren.

Hier ist ein einfaches Beispiel für einen docker-bake.hcl Befehl, der ein einzelnes Build-Ziel definiert:

 target "default" { dockerfile = "app/Dockerfile" contexts = { app = "app/src" shared = "shared-components/src" } tags = ["my-app:latest", "docker.io/my-org/my-app:latest"] }

Wenn Sie docker buildx bake mit dieser Bake-Datei ausführen, wird die app/Dockerfile Dockerfile aus Ihrem Arbeitsverzeichnis geladen. Es hat Zugriff auf die Verzeichnisse app/src und shared-components/src als Build-Kontexte. Dem erstellten Bild werden zwei Tags zugewiesen.

Das default wird automatisch erstellt, wenn Sie docker buildx bake . Sie können auch benannte Ziele definieren, die bei Bedarf erstellt werden können:

 target "app" { // ... }
 $ docker buildx bake app

Verwenden mehrerer Ziele

Sie können gleichzeitig ein weiteres Bild erstellen, indem Sie es als neues Ziel in Ihrer Bake-Datei definieren:

 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"] }

Diese Bilder können gleichzeitig erstellt werden, da sie in einer Gruppe verschachtelt sind. Die api und app -Images werden jedes Mal parallel erstellt, wenn Sie den docker buildx bake Befehl ausführen, da die default automatisch ausgewählt wird. Sie können benannte Gruppen ähnlich wie im obigen Beispiel für benannte Ziele verwenden.

Zielvererbung erstellen

Build-Ziele können voneinander erben, um die Konfiguration wiederzuverwenden. Ein Szenario, in dem dies nützlich sein kann, betrifft Bilder, die für verschiedene Umgebungen angepasst werden müssen. Möglicherweise möchten Sie Image-Varianten, die für Entwicklungszwecke vorgesehen sind, zusätzliche Konfigurationsdateien hinzufügen. Hier ist eine docker-bake.hcl , die dieses Modell demonstriert:

 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"] }

Das backend-dev Ziel erbt alle Eigenschaften des backend -Ziels, überschreibt jedoch den config und wendet ein anderes Tag an.

Sie können eine Vorschau der zusammengeführten Dateistruktur anzeigen, indem Sie den bake -Befehl mit dem Flag --print :

 $ docker buildx bake --print ... "backend-dev": { "context": ".", "contexts": { "config": "api/config-dev", "src": "api/src" }, "dockerfile": "backend/Dockerfile", "tags": [ "backend:dev" ] } ...

Verwenden eines vorherigen Ziels als Basisbild

Manchmal möchten Sie vielleicht, dass ein Erstellungsziel das von einem vorherigen Ziel erstellte Image als eigene Basis verwendet. Dies ist eine Alternative zu mehrstufigen Builds, die verwendet werden können, wenn Ihre Dockerfiles voneinander abhängen, aber nicht zusammengeführt werden können, vielleicht weil sie in verschiedenen Projekten vorhanden sind.

 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"] }

Das Beispiel erstellt zuerst das Ziel org-base-image . Dies könnte einige Dienstprogramme enthalten, die für die containerisierten Workloads Ihrer Organisation üblich sind. Das api -Ziel wird dann mit der Ausgabe des org-base-image Ziels erstellt, auf das als base -Build-Kontext zugegriffen werden kann. Das API-Dockerfile kann jetzt auf Inhalte im Basis-Image verweisen:

 COPY --from=base /utilities/example /usr/bin/example-utility

Dies ist ein leistungsstarkes Muster, mit dem Sie Abhängigkeitslinks zwischen Images erstellen und gleichzeitig separate Dockerfiles verwalten können.

Überschreiben der Eigenschaften von Zielen zur Erstellungszeit

Mit dem docker buildx bake Befehl können Sie die Eigenschaften Ihrer Ziele überschreiben, wenn Sie Ihren Build ausführen:

 $ docker buildx bake --set api.dockerfile="api/Dockerfile-dev"

Dieses Beispiel ändert die Dockerfile des api -Ziels. Der Platzhalter * wird beim Identifizieren des zu ändernden Ziels unterstützt. * allein wählt jedes Ziel aus, während api* alle Ziele ändert, die mit api beginnen.

Variablen setzen

HCL-Dateien können Variablen definieren, auf die Sie in Ihren Build-Zielen verweisen können. Verwenden Sie einen variable , um sie einzurichten:

 variable "TAG" { default = "latest" } group "default" { targets = ["app"] } target "app" { dockerfile = "src/Dockerfile" tags = ["my-app:${TAG}"] }

docker buildx bake mit dieser Konfiguration ausführen, wird das app -Ziel als my-app:latest gekennzeichnet. Sie können den Wert der TAG -Variablen ändern, indem Sie eine Umgebungsvariable setzen, bevor Sie den Befehl ausführen:

 $ TAG=v1 docker buildx bake

Sie können alle Variableninterpolations- und Vergleichsfunktionen der HCL-Sprache verwenden, um Ihre Build-Ziele wiederverwendbar zu machen. Es sind auch Funktionen zum Analysieren und Transformieren Ihrer Werte verfügbar.

Zusammenfassung

Mit gebackenen Buildx-Builds können Sie die Image-Build-Konfiguration als „Ziele“ kapseln, die in einer Datei definiert sind. Wenn Sie buildx bake , werden Images für alle referenzierten Ziele parallel erstellt.

Ziele können voneinander erben und voneinander abhängen. Sie können auch Variablen und Funktionen verwenden, um hochkomplexe und konfigurierbare Build-Pipelines zu erstellen.

Der docker buildx bake -Befehl ist eine übergeordnete Operation, die nicht in jedem Workflow erforderlich ist. Sie müssen es nicht verwenden, wenn Sie einfache Bilder ohne projektübergreifende Abhängigkeiten erstellen. Die Verwendung von docker compose build ist eine bessere Alternative für die meisten Anwendungsfälle, bei der die Build-Konfiguration in Ihrer docker-compose.yml Datei beibehalten wird. Der Wechsel zu gebackenen Builds sollte in Betracht gezogen werden, wenn Sie viele Images gleichzeitig mit unterschiedlichen Variablen, Plattformen, Build-Kontexten und Konfigurationsüberschreibungen erstellen.