Utilisation de Bake avec des contextes supplémentaires
En plus de la clé principale context
qui définit le contexte de build, chaque
cible peut également définir des contextes nommés supplémentaires avec une carte définie avec la clé
contexts
. Ces valeurs correspondent à l'indicateur --build-context
dans la
commande de
construction.
À l'intérieur du Dockerfile, ces contextes peuvent être utilisés avec l'instruction FROM
ou
l'indicateur --from
.
Les valeurs de contexte prises en charge sont :
- Répertoires du système de fichiers local
- Images de conteneurs
- URL Git
- URL HTTP
- Nom d'une autre cible dans le fichier Bake
Épingler l'image alpine
# syntax=docker/dockerfile:1
FROM alpine
RUN echo "Hello world"
target "app" {
contexts = {
alpine = "docker-image://alpine:3.13"
}
}
Utilisation d'un répertoire source secondaire
FROM golang
COPY --from=src . .
# L'exécution de `docker buildx bake app` entraînera que `src` ne pointe pas
# vers une étape de build précédente mais vers le système de fichiers client, ne faisant pas partie du contexte.
target "app" {
contexts = {
src = "../path/to/source"
}
}
Utiliser une cible comme contexte de build
Pour utiliser le résultat d'une cible comme contexte de build d'une autre, spécifiez le nom de la cible
avec le préfixe target:
.
FROM scratch
# syntax=docker/dockerfile:1
FROM baseapp
RUN echo "Hello world"
target "base" {
dockerfile = "baseapp.Dockerfile"
}
target "app" {
contexts = {
baseapp = "target:base"
}
}
Dans la plupart des cas, vous devriez simplement utiliser un seul Dockerfile multi-étapes avec plusieurs cibles pour un comportement similaire. Ce cas n'est recommandé que lorsque vous avez plusieurs Dockerfiles qui ne peuvent pas être facilement fusionnés en un seul.
Dédupliquer le transfert de contexte
NoteDepuis la version 0.17.0 de Buildx et les versions ultérieures, Bake déduplique automatiquement le transfert de contexte pour les cibles qui partagent le même contexte. En plus de la version 0.17.0 de Buildx, le constructeur doit exécuter la version 0.16.0 de BuildKit ou une version ultérieure, et la syntaxe du Dockerfile doit être
docker/dockerfile:1.10
ou une version ultérieure.Si vous remplissez ces conditions, vous n'avez pas besoin de dédupliquer manuellement le transfert de contexte comme décrit dans cette section.
- Pour vérifier votre version de Buildx, exécutez
docker buildx version
.- Pour vérifier votre version de BuildKit, exécutez
docker buildx inspect --bootstrap
et recherchez le champBuildKit version
.- Pour vérifier la version de votre syntaxe Dockerfile, vérifiez la directive d'analyseur
syntax
dans votre Dockerfile. Si elle n'est pas présente, la version par défaut est celle qui est fournie avec votre version actuelle de BuildKit. Pour définir explicitement la version, ajoutez#syntax=docker/dockerfile:1.10
en haut de votre Dockerfile.
Lorsque vous construisez des cibles simultanément, en utilisant des groupes, les contextes de build sont chargés indépendamment pour chaque cible. Si le même contexte est utilisé par plusieurs cibles dans un groupe, ce contexte est transféré une fois pour chaque utilisation. Cela peut avoir un impact significatif sur le temps de construction, en fonction de votre configuration de build. Par exemple, supposons que vous ayez un fichier Bake qui définit le groupe de cibles suivant :
group "default" {
targets = ["target1", "target2"]
}
target "target1" {
target = "target1"
context = "."
}
target "target2" {
target = "target2"
context = "."
}
Dans ce cas, le contexte .
est transféré deux fois lorsque vous construisez le groupe par défaut :
une fois pour target1
et une fois pour target2
.
Si votre contexte est petit et si vous utilisez un constructeur local, les transferts de contexte en double peuvent ne pas être un gros problème. Mais si votre contexte de build est volumineux, ou si vous avez un grand nombre de cibles, ou si vous transférez le contexte sur un réseau vers un constructeur distant, le transfert de contexte devient un goulot d'étranglement des performances.
Pour éviter de transférer le même contexte plusieurs fois, vous pouvez définir un contexte
nommé qui ne charge que les fichiers de contexte, et faire en sorte que chaque cible qui a besoin de
ces fichiers référence ce contexte nommé. Par exemple, le fichier Bake suivant
définit une cible nommée ctx
, qui est utilisée à la fois par target1
et target2
:
group "default" {
targets = ["target1", "target2"]
}
target "ctx" {
context = "."
target = "ctx"
}
target "target1" {
target = "target1"
contexts = {
ctx = "target:ctx"
}
}
target "target2" {
target = "target2"
contexts = {
ctx = "target:ctx"
}
}
Le contexte nommé ctx
représente une étape Dockerfile, qui copie les fichiers
de son contexte (.
). D'autres étapes du Dockerfile peuvent maintenant référencer le
contexte nommé ctx
et, par exemple, monter ses fichiers avec --mount=from=ctx
.
FROM scratch AS ctx
COPY --link . .
FROM golang:alpine AS target1
WORKDIR /work
RUN --mount=from=ctx \
go build -o /out/client ./cmd/client \
FROM golang:alpine AS target2
WORKDIR /work
RUN --mount=from=ctx \
go build -o /out/server ./cmd/server
</rewritten_file>