
Docker Bake vous permet de construire plusieurs images Docker en parallèle avec un seul fichier de configuration. Fini les scripts Bash complexes avec des boucles for — vous centralisez tout dans un fichier HCL (comme Terraform) avec variables, héritage et groupes. Ce guide vous montre comment remplacer vos scripts de build par Docker Bake en 15 minutes.
Ce que vous apprendrez :
- Créer un fichier
docker-bake.hclavec plusieurs targets (frontend, backend) - Utiliser variables et héritage pour éviter la duplication
- Construire pour plusieurs plateformes (linux/amd64, linux/arm64)
- Intégrer Bake dans votre CI/CD (GitHub Actions, GitLab CI)
Prérequis : Docker 20.10+ avec Buildx installé, connaissances de base en Dockerfile.
Pourquoi Docker Bake ?
Section intitulée « Pourquoi Docker Bake ? »Le problème des scripts de build traditionnels
Section intitulée « Le problème des scripts de build traditionnels »Imaginez que vous gérez une application avec frontend (Node.js) et backend (Python Flask). Votre script Bash ressemble probablement à ça :
#!/bin/bash# build.sh — Version avant Docker BakeVERSION="v1.0.0"docker build -t myapp/frontend:${VERSION} ./frontenddocker build -t myapp/backend:${VERSION} ./backendProblèmes :
- Séquentiel : le frontend attend que le backend finisse (perte de temps)
- Duplication : tags répétés, pas de variables centralisées
- Pas de multi-platform : construire pour arm64 nécessite des boucles supplémentaires
- Maintenance difficile : ajouter un service = modifier le script dans 5 endroits
La solution Docker Bake
Section intitulée « La solution Docker Bake »Avec Bake, vous remplacez tout par un fichier docker-bake.hcl :
variable "TAG" { default = "v1.0.0"}
group "default" { targets = ["frontend", "backend"]}
target "frontend" { context = "./frontend" tags = ["myapp/frontend:${TAG}"]}
target "backend" { context = "./backend" tags = ["myapp/backend:${TAG}"]}Commande unique :
docker buildx bake # Construit les 2 en parallèle automatiquementGains immédiats :
- Parallélisme automatique : frontend et backend en simultané
- Variables centralisées : un seul endroit pour gérer les tags
- Réutilisabilité : héritage pour éviter la duplication
- Multi-platform simplifié : ajout de
platforms = ["linux/amd64", "linux/arm64"]et c’est géré
Concepts clés
Section intitulée « Concepts clés »Avant de plonger dans le code, comprenons les 4 éléments fondamentaux de Docker Bake.
1. Targets (cibles de build)
Section intitulée « 1. Targets (cibles de build) »Un target = une image à construire. Comparable à une cible dans un Makefile.
target "frontend" { context = "./frontend" dockerfile = "Dockerfile" tags = ["myapp/frontend:latest"]}Explication : ce target construit l’image myapp/frontend avec le tag défini par la variable TAG en utilisant le Dockerfile dans ./frontend.
2. Groups (groupes de targets)
Section intitulée « 2. Groups (groupes de targets) »Un group = une collection de targets à exécuter ensemble.
group "default" { targets = ["frontend", "backend"]}Utilité : docker buildx bake (sans argument) exécute automatiquement le groupe default. Vous pouvez créer plusieurs groupes (dev, prod, test).
3. Variables
Section intitulée « 3. Variables »Les variables rendent vos configurations dynamiques et réutilisables.
variable "TAG" { default = "v1.0.0"}
target "frontend" { tags = ["myapp/frontend:${TAG}"]}Override en ligne de commande :
docker buildx bake --set *.TAG=v1.0.0 # Change TAG pour tous les targetsdocker buildx bake --set frontend.TAG=v2.0.0 # Pour un target spécifiquedocker buildx bake --set '*.platforms=linux/amd64' # Surcharger platforms4. Héritage
Section intitulée « 4. Héritage »L’héritage évite la duplication en partageant des configurations communes.
target "base" { labels = { "maintainer" = "devops@example.com" "project" = "myapp" }}
target "frontend" { inherits = ["base"] context = "./frontend"}
target "backend" { inherits = ["base"] context = "./backend"}Résultat : frontend et backend héritent automatiquement des labels de base.
Prérequis et installation
Section intitulée « Prérequis et installation »-
Vérifier Docker Buildx
Docker Bake fait partie de Docker Buildx. Si vous avez Docker Desktop, c’est déjà installé.
Fenêtre de terminal docker buildx version# buildx v0.30.0 github.com/docker/buildxSi la commande échoue, installez Buildx.
-
Vérifier le builder actif
Fenêtre de terminal docker buildx ls# NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS# default docker running v0.17.3 linux/amd64Si vous voyez un builder actif (
default), vous êtes prêt. -
Créer un builder multi-platform (optionnel)
Pour construire des images arm64 sur une machine amd64 :
Fenêtre de terminal docker buildx create --name mybuilder --driver docker-container --bootstrapdocker buildx use mybuilderVérification :
Fenêtre de terminal docker buildx ls# mybuilder * docker-container# └─mybuilder0 unix:///var/run/docker.sock running linux/amd64, linux/arm64Le
*indique quemybuilderest actif.
Syntaxe et structure des fichiers Bake
Section intitulée « Syntaxe et structure des fichiers Bake »Docker Bake supporte 3 formats de configuration :
| Format | Extension | Cas d’usage recommandé |
|---|---|---|
| HCL | .hcl | Recommandé — syntaxe Terraform-like, variables natives, fonctions |
| JSON | .json | Génération programmatique (scripts CI/CD) |
| YAML | .yml, .yaml | Réutiliser un fichier Compose existant |
Ordre de recherche automatique (si vous ne spécifiez pas --file) :
compose.yaml,compose.yml,docker-compose.yml,docker-compose.yamldocker-bake.json,docker-bake.override.jsondocker-bake.hcl,docker-bake.override.hcl
Exemple comparatif des 3 formats
Section intitulée « Exemple comparatif des 3 formats »variable "TAG" { default = "latest"}
target "frontend" { context = "./frontend" tags = ["myapp/frontend:${TAG}"] platforms = ["linux/amd64", "linux/arm64"]}{ "variable": { "TAG": { "default": "latest" } }, "target": { "frontend": { "context": "./frontend", "tags": ["myapp/frontend:${TAG}"], "platforms": ["linux/amd64", "linux/arm64"] } }}variable: TAG: default: latest
target: frontend: context: ./frontend tags: - myapp/frontend:${TAG} platforms: - linux/amd64 - linux/arm64Spécifier explicitement un fichier :
docker buildx bake --file custom-bake.hclAnatomie d’un target
Section intitulée « Anatomie d’un target »Un target décrit comment construire une image spécifique. Propriétés principales :
target "frontend" { context = "./frontend" # Dossier source (contexte de build) dockerfile = "Dockerfile" # Fichier Dockerfile à utiliser tags = [ # Tags de l'image résultante "myapp/frontend:v1.0.0", "myapp/frontend:v1" ] args = { # Arguments passés au Dockerfile (ARG) NODE_ENV = "production" } platforms = [ # Architectures cibles "linux/amd64", "linux/arm64" ] labels = { # Métadonnées (labels OCI) "org.opencontainers.image.source" = "https://github.com/me/app" } output = ["type=docker"] # Type de sortie (docker, registry, tar...)}Exécution :
# Toutes les cibles du groupe defaultdocker buildx bake
# Cible spécifiquedocker buildx bake frontend
# Plusieurs cibles explicitesdocker buildx bake frontend backendDéfinition des groups
Section intitulée « Définition des groups »Les groupes vous permettent d’organiser plusieurs cibles en un seul ensemble. Cela permet d’exécuter plusieurs builds en parallèle ou de séquencer des builds en fonction des besoins du projet.
group "default" { targets = ["frontend", "backend"]}
target "frontend" { context = "./frontend" dockerfile = "Dockerfile" tags = ["myapp/frontend:v1.0.0"]}
target "backend" { context = "./backend" dockerfile = "Dockerfile" args = { NODE_ENV = "production" } tags = ["myapp/backend:v1.0.0"]}Héritage
Section intitulée « Héritage »Docker Bake supporte le concept d’héritage, permettant à une cible de build d’hériter des propriétés d’une ou plusieurs autres cibles. Ce mécanisme simplifie la gestion des configurations complexes en réutilisant et en étendant des blocs de construction existants. Par exemple, vous pouvez définir une cible parent avec des configurations communes, puis créer des cibles enfants qui héritent de ces propriétés tout en ajoutant ou en modifiant certains paramètres.
Exemple d’héritage :
target "base" { context = "./" dockerfile = "Dockerfile.base"}
target "frontend" { inherits = ["base"] dockerfile = "Dockerfile.frontend" tags = ["myapp/frontend:v1.0.0"]}
target "backend" { inherits = ["base"] dockerfile = "Dockerfile.backend" args = { NODE_ENV = "production" } tags = ["myapp/backend:v1.0.0"]}Dans cet exemple, les cibles frontend et backend héritent toutes deux des
propriétés de la cible base, ce qui permet de partager des configurations
communes comme le contexte et certaines parties du Dockerfile. Cela réduit la
duplication de code et rend les fichiers de configuration plus faciles à
maintenir.
L’héritage est particulièrement utile dans des projets où plusieurs cibles partagent une grande partie de la même configuration, mais nécessitent des ajustements spécifiques. Il permet de centraliser les configurations communes tout en offrant la flexibilité nécessaire pour adapter chaque build aux besoins spécifiques du service ou de l’application.
Utilisation des variables
Section intitulée « Utilisation des variables »Docker Bake permet d’utiliser des variables pour rendre vos fichiers de
configuration plus dynamiques et réutilisables. Les variables peuvent être
définies dans le fichier de configuration Bake, passées via la ligne de
commande, ou provenant de fichiers .env. Cela permet d’ajuster les builds en
fonction de différents environnements ou configurations sans modifier
directement le fichier Bake.
Exemple de fichier avec variables
Section intitulée « Exemple de fichier avec variables »variable "version" { default = "1.0"}
target "backend" { context = "./backend" tags = ["myapp/backend:${version}"]}Ici, la variable version est utilisée pour générer dynamiquement le tag de
l’image.
Les variables peuvent être déclarées avec une valeur par défaut et peuvent être surchargées en ligne de commande :
docker buildx bake --set version=2.0Expressions
Section intitulée « Expressions »Docker Bake prend en charge l’évaluation des expressions dans les fichiers HCL, ce qui permet d’effectuer des opérations arithmétiques, de définir des valeurs conditionnellement et plus encore.
Opérations arithmétiques
Section intitulée « Opérations arithmétiques »Vous pouvez réaliser des calculs directement dans vos configurations. Par exemple, pour multiplier deux nombres :
sum = 7 * 6
target "default" { args = { answer = sum }}En imprimant le fichier avec --print, Docker Bake évalue et affiche la valeur
calculée :
"args": { "answer": "42"}Opérateurs ternaires
Section intitulée « Opérateurs ternaires »Les opérateurs ternaires permettent de conditionner l’attribution de valeurs. Par exemple, ajouter un tag seulement si une variable n’est pas vide :
variable "TAG" {}
target "default" { tags = [ "my-image:v1.0.0", notequal("", TAG) ? "my-image:${TAG}" : "", ]}Si TAG est vide, seul le tag my-image:v1.0.0 est appliqué.
Expressions avec des variables
Section intitulée « Expressions avec des variables »Les expressions peuvent être combinées avec des variables pour conditionner les arguments de build ou effectuer des calculs. Par exemple :
variable "FOO" { default = 3}
variable "IS_FOO" { default = true}
target "app" { args = { v1 = FOO > 5 ? "higher" : "lower" v2 = IS_FOO ? "yes" : "no" }}Fonctions intégrées
Section intitulée « Fonctions intégrées »Docker Bake propose une série de fonctions intégrées pour manipuler les données dans vos fichiers de configuration. Ces fonctions permettent d’effectuer des opérations comme la manipulation de chaînes, l’évaluation conditionnelle, et la gestion de listes. Par exemple, vous pouvez utiliser des fonctions pour concaténer des chaînes, transformer des variables, ou effectuer des conversions dynamiques.
Exemple de fonction :
target "example" { tags = ["myapp/${upper(var.name)}:${replace(var.version, ".", "_")}"]}Ici, la fonction upper transforme var.name en majuscules et replace
substitue les points dans var.version par des underscores.
Docker Bake prend en charge plusieurs fonctions intégrées qui permettent de manipuler les chaînes de caractères, effectuer des opérations conditionnelles, et gérer des listes dans vos fichiers de configuration. Parmi les fonctions disponibles, on trouve :
upperetlower: convertissent une chaîne de caractères en majuscules ou minuscules.replace: remplace une sous-chaîne par une autre.contains: vérifie si une chaîne ou une liste contient un élément donné.notequal: compare deux valeurs et retourne vrai si elles ne sont pas égales.join: combine les éléments d’une liste en une seule chaîne.
Pour une liste complète et des exemples, consultez la documentation officielle.
Matrices de build
Section intitulée « Matrices de build »Docker Bake permet de définir des matrices de build, ce qui vous permet de construire plusieurs variantes d’une image Docker en une seule commande. Les matrices combinent plusieurs variables pour générer différentes configurations de build, comme des versions spécifiques de l’application ou des architectures cibles.
Exemple de matrice :
target "app" { context = "./app" dockerfile = "Dockerfile" args = { NODE_ENV = ["development", "production"] } platforms = ["linux/amd64", "linux/arm64"]}Cela construit les images pour chaque combinaison d’environnement et de plateforme.
Gestion des contextes
Section intitulée « Gestion des contextes »Docker Bake permet de spécifier des contextes de build pour définir les sources de vos builds, qu’il s’agisse de répertoires locaux, de référentiels Git, ou de fichiers tar. Un contexte de build fournit les fichiers et dossiers nécessaires pour construire l’image Docker. Vous pouvez également utiliser plusieurs contextes dans un même fichier Bake, permettant une flexibilité accrue dans la gestion des sources de vos builds.
target "multi-context" { contexts = { frontend = "./frontend" backend = "./backend" assets = "git://github.com/user/assets-repo.git" } dockerfile = "Dockerfile"}Mise en oeuvre
Section intitulée « Mise en oeuvre »Dans ce tutoriel, nous allons créer un projet simple en utilisant Docker Bake avec un fichier HCL. Nous allons enrichir ce fichier progressivement tout en utilisant des concepts comme les cibles, les variables, les expressions, l’héritage, les contextes, les matrices de build.
Structure du projet
Section intitulée « Structure du projet »Voici la structure de notre projet :
- docker-bake.hcl
Répertoirefrontend/
- Dockerfile
- index.js
Répertoirebackend/
- Dockerfile
- app.py
- requirements.txt
Les fichiers
Section intitulée « Les fichiers »Pour le frontend
Section intitulée « Pour le frontend »FROM node:20-slimWORKDIR /appCOPY package.json .RUN npm installCOPY . .CMD ["node", "index.js"]const http = require('http');
const hostname = '0.0.0.0';const port = 3000;
const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello from Node.js frontend!\n');});
server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`);});Pour le backend
Section intitulée « Pour le backend »FROM python:3.11-slimWORKDIR /appCOPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txtCOPY . .CMD ["python", "app.py"]from flask import Flask
app = Flask(__name__)
@app.route('/')def hello(): return "Hello from Flask backend!"
if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)Flask==3.0.3Werkzeug==3.0.4Étapes de la configuration Docker Bake
Section intitulée « Étapes de la configuration Docker Bake »Dans un premier temps, nous allons créer les deux target pour le backend et le
frontend :
group "default" { targets = [ "backend", "frontend" ]}
target "backend" { context = "./backend" dockerfile = "Dockerfile" tags = ["backend:v1.0.0"]}
target "frontend" { context = "./frontend" dockerfile = "Dockerfile" tags = ["frontend:v1.0.0"]}On créé le groupe default contenant les deux targets backend et frontend.
Validons le contenu du fichier avec la commande suivante :
docker buildx bake --print[+] Building 0.0s (1/1) FINISHED => [internal] load local bake definitions 0.0s => => reading docker-bake.hcl 316B / 316B 0.0s{ "group": { "default": { "targets": [ "backend", "frontend" ] } }, "target": { "backend": { "context": "backend", "dockerfile": "./Dockerfile", "tags": [ "backend:v1.0.0" ] }, "frontend": { "context": "frontend", "dockerfile": "./Dockerfile", "tags": [ "frontend:v1.0.0" ] } }}Étape 2 : Ajout de variables pour la flexibilité
Section intitulée « Étape 2 : Ajout de variables pour la flexibilité »En bon DevOps, nous n’utilisons pas les tags latest. Remplaçons-les par des
versions dans des variables
variable "frontend_version" { default = "1.0.1"}
variable "backend_version" { default = "1.0.17"}
group "default" { targets = [ "backend", "frontend" ]}
target "backend" { context = "./backend" dockerfile = "Dockerfile" tags = ["backend:${backend_version}"]}
target "frontend" { context = "./frontend" dockerfile = "Dockerfile" tags = ["frontend:${frontend_version}"]}On relance la commande de check :
docker buildx bake --print[+] Building 0.0s (1/1) FINISHED => [internal] load local bake definitions 0.0s => => reading docker-bake.hcl 434B / 434B 0.0s{ "group": { "default": { "targets": [ "backend", "frontend" ] } }, "target": { "backend": { "context": "backend", "dockerfile": "Dockerfile", "tags": [ "backend:1.0.17" ] }, "frontend": { "context": "frontend", "dockerfile": "Dockerfile", "tags": [ "frontend:1.0.1" ] } }}On voit que les tags ont pris les bonnes valeurs. Tentons de construire nos images :
docker buildx bakeLe build s’exécute en parallèle automatiquement. Sortie finale :
#16 [backend] exporting to image#16 exporting layers 0.5s done#16 exporting manifest sha256:1e524d50af27... done#16 naming to docker.io/library/backend:1.0.17 done#16 unpacking to docker.io/library/backend:1.0.17 0.2s done#16 DONE 0.8s
#21 [frontend] exporting to image#21 exporting layers 0.3s done#21 exporting manifest sha256:6a9a337553f7... done#21 naming to docker.io/library/frontend:1.0.1 done#21 unpacking to docker.io/library/frontend:1.0.1 0.1s done#21 DONE 0.5sLe build s’est bien passé en parallèle. On vérifie les images :
docker images | grep -E "^(backend|frontend)"backend:1.0.17 6adfe08e5644 210MB 51.1MBfrontend:1.0.1 b597249c44a2 289MB 70.9MBMulti-plateforme (multi-arch)
Section intitulée « Multi-plateforme (multi-arch) »Nous allons construire des images pour plusieurs architectures (amd64, arm64). Pour
cela, il faut ajouter un builder utilisant le driver docker-container :
docker buildx create --driver docker-container --bootstrap --name bake-multiplatform
[+] Building 1.6s (1/1) FINISHED => [internal] booting buildkit 1.6s => => pulling image moby/buildkit:buildx-stable-1 1.2s => => creating container buildx_buildkit_bake-multiplatform0 0.4sbake-multiplatformDéfinissons-le comme builder par défaut :
docker buildx use bake-multiplatformVérifions qu’il supporte bien arm64 :
docker buildx lsNAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMSbake-multiplatform* docker-container \_ bake-multiplatform0 \_ unix:///var/run/docker.sock running v0.26.3 linux/amd64, linux/arm64, linux/386default docker \_ default \_ default running v0.26.2 linux/amd64Le * indique que bake-multiplatform est actif.
Ajoutons dans les targets les plateformes cibles :
target "backend" { context = "./backend" dockerfile = "Dockerfile" tags = ["backend:${backend_version}"] platforms = ["linux/amd64", "linux/arm64"]}
target "frontend" { context = "./frontend" dockerfile = "Dockerfile" tags = ["frontend:${frontend_version}"] platforms = ["linux/amd64", "linux/arm64"]}Lançons le build multi-arch :
docker buildx bake backendExtrait de la sortie montrant les builds parallèles pour les deux architectures :
#0 building with "bake-multiplatform" instance using docker-container driver
#3 DONE 1.5s
#4 [linux/arm64 internal] load metadata for docker.io/library/python:3.11-slim#4 DONE 1.5s
#7 [linux/amd64 1/5] FROM docker.io/library/python:3.11-slim@sha256:5be45...#7 DONE 0.2s
#8 [linux/arm64 1/5] FROM docker.io/library/python:3.11-slim@sha256:5be45...#8 sha256:518abaec... 249B / 249B 0.4s done#8 sha256:068949... 14.31MB / 14.31MB 4.7s done...On voit clairement linux/amd64 et linux/arm64 construits en parallèle.
Ce petit tutoriel montre comment structurer un projet Docker avec Docker Bake, permettant des builds flexibles et optimisés pour différents environnements et plateformes.
Pour approfondir, consultez la documentation Docker Bake.
Overrides et fusion de fichiers
Section intitulée « Overrides et fusion de fichiers »Docker Bake permet de fusionner plusieurs fichiers de configuration pour séparer config commune et config spécifique.
Fichiers override automatiques
Section intitulée « Fichiers override automatiques »Bake charge automatiquement les fichiers *.override.* s’ils existent :
# Bake charge automatiquement ces 2 fichiers si présentsdocker buildx bake# → charge docker-bake.hcl + docker-bake.override.hclCas d’usage :
| Fichier | Contenu |
|---|---|
docker-bake.hcl | Config commune (versionnée en git) |
docker-bake.override.hcl | Config locale (dans .gitignore) |
Exemple :
variable "REGISTRY" { default = "docker.io/myorg"}
target "frontend" { context = "./frontend" tags = ["${REGISTRY}/frontend:v1.0.0"]}# Override local pour dev (non versionné)variable "REGISTRY" { default = "localhost:5000"}
target "frontend" { output = ["type=docker"] # Local, pas push}Fusion manuelle avec —file
Section intitulée « Fusion manuelle avec —file »docker buildx bake --file base.hcl --file prod.hcl --file ci.hclOrdre de priorité : le dernier fichier prime en cas de conflit.
Cas d’usage CI/CD :
# Base commune + config prod + overrides CIdocker buildx bake \ --file docker-bake.hcl \ --file ci/prod.hcl \ --set '*.TAG=${GIT_SHA}'Cache registry pour builds rapides
Section intitulée « Cache registry pour builds rapides »Le cache registry accélère drastiquement les builds CI/CD en réutilisant les layers entre pipelines.
Configuration du cache
Section intitulée « Configuration du cache »variable "REGISTRY" { default = "ghcr.io/myorg" }
target "_common" { cache-from = ["type=registry,ref=${REGISTRY}/myapp:buildcache"] cache-to = ["type=registry,ref=${REGISTRY}/myapp:buildcache,mode=max"]}
target "frontend" { inherits = ["_common"] context = "./frontend" tags = ["${REGISTRY}/myapp-frontend:v1.0.0"]}Types de cache
Section intitulée « Types de cache »| Type | Usage | Commande |
|---|---|---|
| inline | Cache intégré dans l’image | cache-to=["type=inline"] |
| registry | Cache dédié dans registry (recommandé CI/CD) | cache-to=["type=registry,ref=..."] |
| local | Cache local sur disque | cache-to=["type=local,dest=/tmp/cache"] |
| gha | GitHub Actions cache | cache-to=["type=gha"] |
Mode de cache
Section intitulée « Mode de cache »cache-to = ["type=registry,ref=...,mode=max"] # max = tous les layers# mode=min (défaut) = layers de l'image finale uniquementGains typiques : réduction de 80-90% du temps de build CI/CD après le premier run.
Workflow CI/CD complet (GitHub Actions)
Section intitulée « Workflow CI/CD complet (GitHub Actions) »Exemple production-ready avec cache, tags dynamiques, multi-platform, provenance.
Fichier Bake
Section intitulée « Fichier Bake »variable "REGISTRY" { default = "ghcr.io/myorg" }variable "TAG" { default = "dev" }variable "GIT_SHA" { default = "" }variable "PLATFORMS" { default = ["linux/amd64"] }
target "_common" { platforms = PLATFORMS labels = { "org.opencontainers.image.source" = "https://github.com/myorg/myrepo" "org.opencontainers.image.created" = "${timestamp()}" "org.opencontainers.image.revision" = GIT_SHA } cache-from = ["type=registry,ref=${REGISTRY}/buildcache:${TAG}"] cache-to = ["type=registry,ref=${REGISTRY}/buildcache:${TAG},mode=max"] output = ["type=registry"] attest = [ "type=provenance,mode=max", "type=sbom" ]}
target "frontend" { inherits = ["_common"] context = "./frontend" dockerfile = "Dockerfile" tags = [ "${REGISTRY}/myapp-frontend:${TAG}", notequal("", GIT_SHA) ? "${REGISTRY}/myapp-frontend:${GIT_SHA}" : "" ]}
target "backend" { inherits = ["_common"] context = "./backend" dockerfile = "Dockerfile" tags = [ "${REGISTRY}/myapp-backend:${TAG}", notequal("", GIT_SHA) ? "${REGISTRY}/myapp-backend:${GIT_SHA}" : "" ]}Workflow GitHub Actions
Section intitulée « Workflow GitHub Actions »name: Build Images
on: push: branches: [main] pull_request:
jobs: build: runs-on: ubuntu-latest permissions: contents: read packages: write attestations: write id-token: write steps: - uses: actions/checkout@v4.2.2
- name: Set up Docker Buildx uses: docker/setup-buildx-action@v3.9.0
- name: Login to GitHub Container Registry uses: docker/login-action@v3.3.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push run: | docker buildx bake \ --set '*.REGISTRY=ghcr.io/${{ github.repository_owner }}' \ --set '*.TAG=${{ github.ref_name }}' \ --set '*.GIT_SHA=${{ github.sha }}' \ --set '*.PLATFORMS=linux/amd64,linux/arm64'Points clés :
- Tags dynamiques : branche + SHA
- Multi-platform : amd64 + arm64 en un seul run
- Cache registry : réutilise layers entre runs
- Provenance + SBOM : attestations intégrées (SLSA)
- Permissions minimales : principe du moindre privilège
Compose file comme entrée Bake
Section intitulée « Compose file comme entrée Bake »Si vous avez déjà un compose.yaml, Bake peut l’utiliser directement comme source.
Exemple Compose
Section intitulée « Exemple Compose »services: frontend: build: context: ./frontend args: NODE_ENV: production platforms: - linux/amd64 - linux/arm64 image: myapp/frontend:v1.0.0
backend: build: context: ./backend image: myapp/backend:v1.0.0Utilisation avec Bake
Section intitulée « Utilisation avec Bake »# Bake charge automatiquement compose.yamldocker buildx bake
# Ou explicitementdocker buildx bake --file compose.yaml
# Combiner Compose + Bake HCL (overrides)docker buildx bake --file compose.yaml --file docker-bake.hclCas d’usage : migration progressive vers Bake sans réécrire toute la config.
À retenir
Section intitulée « À retenir »- Bake = orchestrateur de builds, pas d’exécution (complément de Compose)
- HCL recommandé : variables natives, fonctions, héritage naturel
- Parallélisme automatique : tous les targets sans dépendances = parallèle
--setest votre ami : surcharges dynamiques pour CI/CD (*.TAG,*.PLATFORMS)- Cache registry : gain 80-90% temps build en CI avec
cache-from/cache-to - Overrides :
docker-bake.override.hclou--filemultiple pour séparer config - Multi-platform production :
output=["type=registry"]+platforms=[...] - Compose file compatible : Bake peut lire
compose.yamlcomme source