Come utilizzare Docker Buildx Bake per creare pipeline di costruzione di immagini complesse
Pubblicato: 2022-08-10 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.