Come utilizzare Docker Buildx Bake per creare pipeline di costruzione di immagini complesse

Pubblicato: 2022-08-10

Grafica che mostra il logo Docker

Il gruppo di comandi docker buildx usa BuildKit per esporre funzionalità avanzate di creazione di immagini. Le build preparate sono una funzionalità di alto livello che può essere utilizzata per definire pipeline di build automatizzate. Ti consentono di produrre più immagini da un'unica operazione di creazione.

I flussi di lavoro Baked sono utili quando desideri pubblicare diverse varianti delle tue immagini o creare più progetti collegati in parallelo. In questo articolo tratteremo le funzionalità chiave di docker buildx bake e come puoi usarle per semplificare build complesse.

Iniziare

Il comando docker buildx bake esegue più "target" di build che producono ciascuno un'immagine del contenitore. Gli obiettivi vengono eseguiti in parallelo ove possibile per massimizzare le prestazioni. I target possono anche fare riferimento direttamente ai predecessori per creare pipeline sequenziali.

Le destinazioni di compilazione possono essere definite utilizzando diversi meccanismi, inclusi i file Docker Compose esistenti. Buildx creerà automaticamente tutte le immagini identificate nel file.

Le funzionalità più avanzate vengono visualizzate quando elenchi le destinazioni di build in file JSON o HCL. Questi supportano variabili, funzioni e interpolazione di valori per personalizzare le build.

Il comando buildx bake cerca i seguenti file in ordine:

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

È possibile specificare un file diverso con il flag del comando -f .

Costruisci obiettivi

Gli obiettivi di build incapsulano tutta la configurazione relativa alla tua build. Includono dettagli come

  • il percorso del Dockerfile da compilare
  • crea percorsi di contesto, definendo il contenuto disponibile all'interno del tuo Dockerfile
  • tag ed etichette da allegare alle immagini di output
  • le piattaforme per la produzione di immagini.

Un elenco completo dei campi di configurazione supportati è disponibile nella documentazione. In precedenza potresti aver fornito queste impostazioni come flag della riga di comando per docker buildx build (o anche semplice docker build ), costringendoti a ricordare ogni volta i valori corretti. Con buildx bake puoi utilizzare in modo affidabile gli stessi valori definendoli nel tuo file bake controllato dalla versione.

Ecco un semplice esempio di comando docker-bake.hcl che definisce una singola destinazione di compilazione:

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

L'esecuzione di docker buildx bake con questo file Bake caricherà l' app/Dockerfile Dockerfile dalla tua directory di lavoro. Avrà accesso alle directory app/src e shared-components/src come contesti di compilazione. All'immagine prodotta verranno assegnati due tag.

La destinazione default viene creata automaticamente quando esegui docker buildx bake . Puoi anche definire obiettivi con nome che possono essere costruiti su richiesta:

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

Utilizzo di più bersagli

Puoi creare un'altra immagine contemporaneamente definendola come una nuova destinazione all'interno del tuo file di cottura:

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

Queste immagini possono essere create contemporaneamente perché sono nidificate in un gruppo. Le immagini api e app verranno create in parallelo ogni volta che esegui il comando docker buildx bake poiché il gruppo default viene selezionato automaticamente. È possibile utilizzare i gruppi denominati in modo simile all'esempio delle destinazioni con nome sopra.

Costruisci l'eredità di destinazione

Le destinazioni di compilazione possono ereditare l'una dall'altra per riutilizzare la configurazione. Uno scenario in cui ciò può essere utile riguarda le immagini che devono essere personalizzate per ambienti diversi. Potresti voler aggiungere file di configurazione extra alle varianti di immagine destinate all'uso in fase di sviluppo. Ecco un docker-bake.hcl che dimostra questo modello:

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

La destinazione backend-dev eredita tutte le proprietà della destinazione backend ma sovrascrive il contesto di config e applica un tag diverso.

È possibile visualizzare in anteprima la struttura del file unito eseguendo il comando bake con il flag --print :

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

Utilizzo di un obiettivo precedente come immagine di base

A volte potresti volere che una destinazione di compilazione utilizzi l'immagine creata da una destinazione precedente come propria base. Questa è un'alternativa alle build multifase che possono essere utilizzate quando i tuoi Dockerfile dipendono l'uno dall'altro ma non possono essere uniti, forse perché esistono in progetti diversi.

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

L'esempio crea prima la destinazione org-base-image dell'organizzazione. Questo potrebbe contenere alcune utilità comuni ai carichi di lavoro containerizzati dell'organizzazione. La destinazione api viene quindi compilata con l'output della destinazione org-base-image accessibile come contesto di compilazione di base . L'API Dockerfile ora può fare riferimento al contenuto all'interno dell'immagine di base:

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

Questo è un modello potente che ti consente di creare collegamenti di dipendenza tra le immagini mantenendo Dockerfile separati.

Sovrascrivere le proprietà degli obiettivi in ​​fase di compilazione

Il comando docker buildx bake ti consente di sovrascrivere le proprietà dei tuoi target quando esegui la tua build:

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

Questo esempio modifica il Dockerfile della destinazione api . Il carattere jolly * è supportato quando si identifica la destinazione da modificare. * da solo seleziona ogni target mentre api* modificherà tutti i target che iniziano con api .

Impostazione delle variabili

I file HCL possono definire variabili a cui puoi fare riferimento nelle tue destinazioni di build. usa un blocco variable per impostarli:

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

L'esecuzione di docker buildx bake con questa configurazione taggherà la destinazione app come my-app:latest . È possibile modificare il valore della variabile TAG impostando una variabile di ambiente prima di eseguire il comando:

 $ TAG=v1 docker buildx bake

Puoi utilizzare tutte le capacità di interpolazione e confronto delle variabili del linguaggio HCL per rendere riutilizzabili i tuoi target di build. Sono disponibili anche funzioni per analizzare e trasformare i tuoi valori.

Riepilogo

Le build Baked Buildx ti consentono di incapsulare la configurazione della build dell'immagine come "bersagli" definiti in un file. Quando esegui buildx bake , le immagini per tutte le destinazioni di riferimento vengono create in parallelo.

I target possono ereditare e dipendere l'uno dall'altro. Puoi anche utilizzare variabili e funzioni per creare pipeline di build altamente complesse e configurabili.

Il comando docker buildx bake è un'operazione di alto livello che non è necessaria in ogni flusso di lavoro. Non è necessario utilizzarlo quando crei immagini semplici senza dipendenze tra progetti. L'uso di docker compose build è un'alternativa migliore per la maggior parte dei casi d'uso che mantiene la configurazione di build nel file docker-compose.yml . Il passaggio a build cotte dovrebbe essere preso in considerazione quando stai creando molte immagini contemporaneamente utilizzando diverse variabili, piattaforme, contesti di build e sostituzioni di configurazione.