Docker Bake

Tous les exemples peuvent être retrouvés dans ce repo ici

C’est quoi Docker Bake ?

Comme dit dans la documentation Bake, Bake est une surcouche de la commande docker build qui permet de définir la façon de build une image Docker.

Bake permet aussi de builder plusieurs images en parallèle, pour plusieurs plateformes,s de créer directement plusieurs tags sur une même image, de builder la même image avec des build-arg différents… Et tout cela grâce à un fichier et une seule commande Docker.

Il est possible de configurer son build Bake via différents formats de fichiers : JSON, Compose, et HCL.

Dans la suite de ce post, tous les exemples seront en HCL.

Mise en situation

Imaginons que j’aie besoin de builder une image Docker avec différents arguments. Le plus simple pour moi serait de faire un script Bash qui exécute 3 commandes docker, en passant ces arguments.

Quelque chose comme ça :

#!/bin/bash

set -eu

echo "START BUILDING IMAGES"

base_image_tag="base-image"

child_images_tag=("toto" "tata" "titi")

docker build -t $base_image_tag .

for child_tag in "${child_images_tag[@]}"
do
  docker build -f child.dockerfile \
  -t "$child_tag-image" \
  --build-arg CMD_ARG=$child_tag \
  --build-context baseapp="docker-image://$base_image_tag" \
  .
done

echo "DONE"

Notez que l’on utilise un build context afin de permettre l’héritage entre l’image de base et ses enfants.

“Job done”, c’est réglé, on débauche. Oui, mais ici l’exemple est évidemment plus simple que ce dont on peut réellement avoir besoin.

Imaginons que chaque image prenne 4 minutes à se build. Ici, j’attendrais donc 12 minutes au total. Alors qu’en utilisant Bake, je pourrais paralléliser mes builds, en sachant que Bake essaie aussi d’optimiser le caching des layers entre chaque build.

Équivalent HCL du script Bash

group "default" {
	targets = [
		"base",
		"childs"
	]
}

target "base" {
	dockerfile = "Dockerfile"
	context = "."
	tags = [
		"base-image"
	]
}

target "childs" {
	name = "image-${tag}"
	dockerfile = "child.dockerfile"
	contexts = {
		baseapp = "target:base"
	}
	tags = [
		"${tag}-image"
	]
	args = {
		CMD_ARG = "${tag}"
	}
	matrix = {
		tag = [
			"toto",
			"tata",
			"titi"
		]
	}
}

Il me suffit ensuite d’exécuter la commande, et mes quatre images seront buildées.

docker buildx bake

Je change tous mes scripts Bash ?

Honnêtement, si vous ne sentez pas le besoin d’accélérer vos builds d’image, c’est que vous n’avez pas besoin de perdre votre temps à migrer vers Bake (après, c’est toujours fun d’apprendre).

Bake permet bien plus que ce qui est présenté dans ce bref post de blog, et je vous invite à aller lire la documentation officielle pour découvrir : targets, groups, variables, fonctions, matrices, et bien d’autres.

Lisez la Doc !