⚠️ Traduction non officielle - Cette documentation est une traduction communautaire non officielle de Docker.

Contexte de build

Les commandes docker build et docker buildx build construisent des images Docker à partir d'un Dockerfile et d'un contexte.

Qu'est-ce qu'un contexte de build ?

Le contexte de build est l'ensemble des fichiers auxquels votre build peut accéder. L'argument positionnel que vous passez à la commande build spécifie le contexte que vous voulez utiliser pour le build :

$ docker build [OPTIONS] PATH | URL | -
                         ^^^^^^^^^^^^^^

Vous pouvez passer n'importe lequel des inputs suivants comme contexte pour un build :

  • Le chemin relatif ou absolu vers un répertoire local
  • Une URL distante d'un dépôt Git, tarball, ou fichier texte
  • Un fichier texte ou tarball envoyé à la commande docker build via l'entrée standard

Contextes de système de fichiers

Lorsque votre contexte de build est un répertoire local, un dépôt Git distant, ou un fichier tar, alors cela devient l'ensemble des fichiers auxquels le constructeur peut accéder pendant le build. Les instructions de build telles que COPY et ADD peuvent référencer n'importe quel des fichiers et répertoires dans le contexte.

Un contexte de build de système de fichiers est traité récursivement :

  • Lorsque vous spécifiez un répertoire local ou un tarball, tous les sous-répertoires sont inclus
  • Lorsque vous spécifiez un dépôt Git distant, le dépôt et tous les sous-modules sont inclus

Pour plus d'informations sur les différents types de contextes de système de fichiers que vous pouvez utiliser avec vos builds, voir :

Contextes de fichier texte

Lorsque votre contexte de build est un fichier texte, le constructeur interprète le fichier comme un Dockerfile. Avec cette approche, le build n'utilise pas de contexte de système de fichiers.

Pour plus d'informations, voir contexte de build vide.

Contexte local

Pour utiliser un contexte de build local, vous pouvez spécifier un chemin de fichier relatif ou absolu à la commande docker build. L'exemple suivant montre une commande build qui utilise le répertoire courant (.) comme contexte de build :

$ docker build .
...
#16 [internal] load build context
#16 sha256:23ca2f94460dcbaf5b3c3edbaaa933281a4e0ea3d92fe295193e4df44dc68f85
#16 transferring context: 13.16MB 2.2s done
...

Cela rend les fichiers et répertoires du répertoire de travail courant disponibles pour le constructeur. Le constructeur charge les fichiers dont il a besoin depuis le contexte de build quand nécessaire.

Vous pouvez également utiliser des tarballs locaux comme contexte de build, en envoyant les contenus du tarball à la commande docker build. Voir Tarballs.

Répertoires locaux

Considérez la structure de répertoire suivante :

.
├── index.ts
├── src/
├── Dockerfile
├── package.json
└── package-lock.json

Les instructions Dockerfile peuvent référencer et inclure ces fichiers dans le build si vous passez ce répertoire comme contexte.

# syntax=docker/dockerfile:1
FROM node:latest
WORKDIR /src
COPY package.json package-lock.json .
RUN npm ci
COPY index.ts src .
$ docker build .

Contexte local avec Dockerfile depuis stdin

Utilisez la syntaxe suivante pour construire une image en utilisant des fichiers sur votre système de fichiers local, tout en utilisant un Dockerfile depuis stdin.

$ docker build -f- <PATH>

La syntaxe utilise l'option -f (ou --file) pour spécifier le Dockerfile à utiliser, et elle utilise un trait d'union (-) comme nom de fichier pour instruire Docker de lire le Dockerfile depuis stdin.

L'exemple suivant utilise le répertoire courant (.) comme contexte de build, et construit une image en utilisant un Dockerfile passé via stdin en utilisant un here-document.

# créer un répertoire de travail
mkdir example
cd example

# créer un fichier d'exemple
touch somefile.txt

# construire une image en utilisant le répertoire courant comme contexte
# et un Dockerfile passé via stdin
docker build -t myimage:latest -f- . <<EOF
FROM busybox
COPY somefile.txt ./
RUN cat /somefile.txt
EOF

Tarballs locaux

Lorsque vous envoyez un tarball à la commande build, le build utilise le contenu du tarball comme contexte de système de fichiers.

Par exemple, étant donné le répertoire de projet suivant :

.
├── Dockerfile
├── Makefile
├── README.md
├── main.c
├── scripts
├── src
└── test.Dockerfile

Vous pouvez créer un tarball du répertoire et l'envoyer au build pour l'utiliser comme contexte :

$ tar czf foo.tar.gz *
$ docker build - < foo.tar.gz

Le build résout le Dockerfile depuis le contexte tarball. Vous pouvez utiliser le flag --file pour spécifier le nom et l'emplacement du Dockerfile relativement à la racine du tarball. La commande suivante construit en utilisant test.Dockerfile dans le tarball :

$ docker build --file test.Dockerfile - < foo.tar.gz

Contexte distant

Vous pouvez spécifier l'adresse d'un dépôt Git distant, tarball, ou fichier texte comme votre contexte de build.

  • Pour les dépôts Git, le constructeur clone automatiquement le dépôt. Voir Dépôts Git.
  • Pour les tarballs, le constructeur télécharge et extrait le contenu du tarball. Voir Tarballs.

Si le tarball distant est un fichier texte, le constructeur ne reçoit aucun contexte de système de fichiers, et suppose plutôt que le fichier distant est un Dockerfile. Voir Contexte de build vide.

Dépôts Git

Lorsque vous passez une URL pointant vers l'emplacement d'un dépôt Git comme argument à docker build, le constructeur utilise le dépôt comme contexte de build.

Le constructeur effectue un clone superficiel du dépôt, téléchargeant uniquement le commit HEAD, pas tout l'historique.

Le constructeur clone récursivement le dépôt et tous les sous-modules qu'il contient.

$ docker build https://github.com/user/myrepo.git

Par défaut, le constructeur clone le dernier commit sur la branche par défaut du dépôt que vous spécifiez.

Fragments d'URL

Vous pouvez ajouter des fragments d'URL à l'adresse du dépôt Git pour faire en sorte que le constructeur clone une branche, un tag, ou un sous-répertoire spécifique d'un dépôt.

Le format du fragment d'URL est #ref:dir, où :

  • ref est le nom de la branche, du tag, ou du hash de commit
  • dir est un sous-répertoire à l'intérieur du dépôt

Par exemple, la commande suivante utilise la branche container, et le sous-répertoire docker dans cette branche, comme contexte de build :

$ docker build https://github.com/user/myrepo.git#container:docker

Le tableau suivant représente tous les suffixes valides avec leurs contextes de build :

Suffixe de syntaxe de build Commit utilisé Contexte de build utilisé
myrepo.git refs/heads/<branche par défaut> /
myrepo.git#mytag refs/tags/mytag /
myrepo.git#mybranch refs/heads/mybranch /
myrepo.git#pull/42/head refs/pull/42/head /
myrepo.git#:myfolder refs/heads/<branche par défaut> /myfolder
myrepo.git#master:myfolder refs/heads/master /myfolder
myrepo.git#mytag:myfolder refs/tags/mytag /myfolder
myrepo.git#mybranch:myfolder refs/heads/mybranch /myfolder

Lorsque vous utilisez un hash de commit comme ref dans le fragment d'URL, utilisez la chaîne SHA-1 complète de 40 caractères du commit. Un hash court, par exemple un hash tronqué à 7 caractères, n'est pas supporté.

# ✅ Ceci fonctionne :
docker build github.com/docker/buildx#d4f088e689b41353d74f1a0bfcd6d7c0b213aed2
# ❌ Ceci ne fonctionne pas car le hash de commit est tronqué :
docker build github.com/docker/buildx#d4f088e

Garder le répertoire .git

Par défaut, BuildKit ne garde pas le répertoire .git lors de l'utilisation de contextes Git. Vous pouvez configurer BuildKit pour garder le répertoire en définissant l' argument de build BUILDKIT_CONTEXT_KEEP_GIT_DIR. Ceci peut être utile si vous voulez récupérer des informations Git pendant votre build :

# syntax=docker/dockerfile:1
FROM alpine
WORKDIR /src
RUN --mount=target=. \
  make REVISION=$(git rev-parse HEAD) build
$ docker build \
  --build-arg BUILDKIT_CONTEXT_KEEP_GIT_DIR=1
  https://github.com/user/myrepo.git#main

Dépôts privés

Lorsque vous spécifiez un contexte Git qui est également un dépôt privé, le constructeur a besoin que vous fournissiez les identifiants d'authentification nécessaires. Vous pouvez utiliser soit l'authentification SSH soit basée sur token.

Buildx détecte et utilise automatiquement les identifiants SSH si le contexte Git que vous spécifiez est une adresse SSH ou Git. Par défaut, ceci utilise $SSH_AUTH_SOCK. Vous pouvez configurer les identifiants SSH à utiliser avec le flag --ssh.

$ docker buildx build --ssh default [email protected]:user/private.git

Si vous voulez utiliser l'authentification basée sur token à la place, vous pouvez passer le token en utilisant le flag --secret.

$ GIT_AUTH_TOKEN=<token> docker buildx build \
  --secret id=GIT_AUTH_TOKEN \
  https://github.com/user/private.git
Note

N'utilisez pas --build-arg pour les secrets.

Contexte distant avec Dockerfile depuis stdin

Utilisez la syntaxe suivante pour construire une image en utilisant des fichiers sur votre système de fichiers local, tout en utilisant un Dockerfile depuis stdin.

$ docker build -f- <URL>

La syntaxe utilise l'option -f (ou --file) pour spécifier le Dockerfile à utiliser, et elle utilise un trait d'union (-) comme nom de fichier pour instruire Docker de lire le Dockerfile depuis stdin.

Ceci peut être utile dans des situations où vous voulez construire une image depuis un dépôt qui ne contient pas de Dockerfile. Ou si vous voulez construire avec un Dockerfile personnalisé, sans maintenir votre propre fork du dépôt.

L'exemple suivant construit une image en utilisant un Dockerfile depuis stdin, et ajoute le fichier hello.c depuis le dépôt hello-world sur GitHub.

docker build -t myimage:latest -f- https://github.com/docker-library/hello-world.git <<EOF
FROM busybox
COPY hello.c ./
EOF

Tarballs distants

Si vous passez l'URL vers un tarball distant, l'URL elle-même est envoyée au constructeur.

$ docker build http://server/context.tar.gz
#1 [internal] load remote build context
#1 DONE 0.2s

#2 copy /context /
#2 DONE 0.1s
...

L'opération de téléchargement sera effectuée sur l'hôte où le démon BuildKit s'exécute. Notez que si vous utilisez un contexte Docker distant ou un constructeur distant, ce n'est pas nécessairement la même machine que celle où vous exécutez la commande build. BuildKit récupère le context.tar.gz et l'utilise comme contexte de build. Les contextes tarball doivent être des archives tar conformes au format tar Unix standard et peuvent être compressés avec l'un des formats xz, bzip2, gzip ou identity (pas de compression).

Contexte vide

Lorsque vous utilisez un fichier texte comme contexte de build, le constructeur interprète le fichier comme un Dockerfile. Utiliser un fichier texte comme contexte signifie que le build n'a pas de contexte de système de fichiers.

Vous pouvez construire avec un contexte de build vide lorsque votre Dockerfile ne dépend d'aucun fichier local.

Comment construire sans contexte

Vous pouvez passer le fichier texte en utilisant un flux d'entrée standard, ou en pointant vers l' URL d'un fichier texte distant.

$ docker build - < Dockerfile
Get-Content Dockerfile | docker build -
docker build -t myimage:latest - <<EOF
FROM busybox
RUN echo "hello world"
EOF
$ docker build https://raw.githubusercontent.com/dvdksn/clockbox/main/Dockerfile

Lorsque vous construisez sans contexte de système de fichiers, les instructions Dockerfile telles que COPY ne peuvent pas référencer des fichiers locaux :

$ ls
main.c
$ docker build -<<< $'FROM scratch\nCOPY main.c .'
[+] Building 0.0s (4/4) FINISHED
 => [internal] load build definition from Dockerfile       0.0s
 => => transferring dockerfile: 64B                        0.0s
 => [internal] load .dockerignore                          0.0s
 => => transferring context: 2B                            0.0s
 => [internal] load build context                          0.0s
 => => transferring context: 2B                            0.0s
 => ERROR [1/1] COPY main.c .                              0.0s
------
 > [1/1] COPY main.c .:
------
Dockerfile:2
--------------------
   1 |     FROM scratch
   2 | >>> COPY main.c .
   3 |
--------------------
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref 7ab2bb61-0c28-432e-abf5-a4c3440bc6b6::4lgfpdf54n5uqxnv9v6ymg7ih: "/main.c": not found

Fichiers .dockerignore

Vous pouvez utiliser un fichier .dockerignore pour exclure des fichiers ou répertoires du contexte de build.

# .dockerignore
node_modules
bar

Ceci aide à éviter d'envoyer des fichiers et répertoires non désirés au constructeur, améliorant la vitesse de build, surtout lors de l'utilisation d'un constructeur distant.

Nom de fichier et emplacement

Lorsque vous exécutez une commande build, le client build recherche un fichier nommé .dockerignore dans le répertoire racine du contexte. Si ce fichier existe, les fichiers et répertoires qui correspondent aux motifs dans les fichiers sont supprimés du contexte de build avant qu'il ne soit envoyé au constructeur.

Si vous utilisez plusieurs Dockerfiles, vous pouvez utiliser différents fichiers ignore pour chaque Dockerfile. Vous faites cela en utilisant une convention de nommage spéciale pour les fichiers ignore. Placez votre fichier ignore dans le même répertoire que le Dockerfile, et préfixez le fichier ignore avec le nom du Dockerfile, comme montré dans l'exemple suivant.

.
├── index.ts
├── src/
├── docker
│   ├── build.Dockerfile
│   ├── build.Dockerfile.dockerignore
│   ├── lint.Dockerfile
│   ├── lint.Dockerfile.dockerignore
│   ├── test.Dockerfile
│   └── test.Dockerfile.dockerignore
├── package.json
└── package-lock.json

Un fichier ignore spécifique au Dockerfile prend la précédence sur le fichier .dockerignore à la racine du contexte de build si les deux existent.

Syntaxe

Le fichier .dockerignore est une liste de motifs séparés par des nouvelles lignes similaire aux globs de fichiers des shells Unix. Les barres obliques de début et de fin dans les motifs ignore sont ignorées. Les motifs suivants excluent tous un fichier ou répertoire nommé bar dans le sous-répertoire foo sous la racine du contexte de build :

  • /foo/bar/
  • /foo/bar
  • foo/bar/
  • foo/bar

Si une ligne dans le fichier .dockerignore commence par # dans la colonne 1, alors cette ligne est considérée comme un commentaire et est ignorée avant d'être interprétée par le CLI.

#/this/is/a/comment

Si vous êtes intéressé à apprendre les détails précis de la logique de correspondance de motifs .dockerignore, consultez le dépôt moby/patternmatcher sur GitHub, qui contient le code source.

Correspondance

L'extrait de code suivant montre un exemple de fichier .dockerignore.

# comment
*/temp*
*/*/temp*
temp?

Ce fichier provoque le comportement de build suivant :

Règle Comportement
# comment Ignoré.
*/temp* Exclut les fichiers et répertoires dont les noms commencent par temp dans tout sous-répertoire immédiat de la racine. Par exemple, le fichier simple /somedir/temporary.txt est exclu, ainsi que le répertoire /somedir/temp.
*/*/temp* Exclut les fichiers et répertoires commençant par temp de tout sous-répertoire qui est à deux niveaux sous la racine. Par exemple, /somedir/subdir/temporary.txt est exclu.
temp? Exclut les fichiers et répertoires dans le répertoire racine dont les noms sont une extension d'un caractère de temp. Par exemple, /tempa et /tempb sont exclus.

La correspondance est effectuée en utilisant les règles de la fonction filepath.Match de Go. Une étape de prétraitement utilise la fonction filepath.Clean de Go pour supprimer les espaces et enlever . et ... Les lignes qui sont vides après le prétraitement sont ignorées.

Note

Pour des raisons historiques, le motif . est ignoré.

Au-delà des règles filepath.Match de Go, Docker prend également en charge une chaîne joker spéciale ** qui correspond à un nombre quelconque de répertoires (y compris zéro). Par exemple, **/*.go exclut tous les fichiers qui se terminent par .go trouvés n'importe où dans le contexte de build.

Vous pouvez utiliser le fichier .dockerignore pour exclure le Dockerfile et les fichiers .dockerignore. Ces fichiers sont toujours envoyés au constructeur car ils sont nécessaires pour exécuter le build. Mais vous ne pouvez pas copier les fichiers dans l'image en utilisant ADD, COPY, ou des montages bind.

Négation des correspondances

Vous pouvez préfixer les lignes avec un ! (point d'exclamation) pour faire des exceptions aux exclusions. Voici un exemple de fichier .dockerignore qui utilise ce mécanisme :

*.md
!README.md

Tous les fichiers markdown directement sous le répertoire de contexte sauf README.md sont exclus du contexte. Notez que les fichiers markdown sous les sous-répertoires sont toujours inclus.

Le placement des règles d'exception ! influence le comportement : la dernière ligne du .dockerignore qui correspond à un fichier particulier détermine s'il est inclus ou exclu. Considérez l'exemple suivant :

*.md
!README*.md
README-secret.md

Aucun fichier markdown n'est inclus dans le contexte sauf les fichiers README autres que README-secret.md.

Maintenant considérez cet exemple :

*.md
README-secret.md
!README*.md

Tous les fichiers README sont inclus. La ligne du milieu n'a aucun effet car !README*.md correspond à README-secret.md et vient en dernier.

Contextes nommés

En plus du contexte de build par défaut (l'argument positionnel de la commande docker build), vous pouvez également passer des contextes nommés supplémentaires aux builds.

Les contextes nommés sont spécifiés en utilisant le flag --build-context, suivi d'une paire nom-valeur. Ceci vous permet d'inclure des fichiers et répertoires de sources multiples pendant le build, tout en les gardant logiquement séparés.

$ docker build --build-context docs=./docs .

Dans cet exemple :

  • Le contexte nommé docs pointe vers le répertoire ./docs.
  • Le contexte par défaut (.) pointe vers le répertoire de travail courant.

Utilisation des contextes nommés dans un Dockerfile

Les instructions Dockerfile peuvent référencer les contextes nommés comme s'ils étaient des étapes dans un build multi-étapes.

Par exemple, le Dockerfile suivant :

  1. Utilise une instruction COPY pour copier des fichiers depuis le contexte par défaut dans l' étape de build courante.
  2. Monte les fichiers dans un contexte nommé pour traiter les fichiers dans le cadre du build.
# syntax=docker/dockerfile:1
FROM buildbase
WORKDIR /app

# Copier tous les fichiers depuis le contexte par défaut dans /app/src dans le conteneur de build
COPY . /app/src
RUN make bin

# Monter les fichiers depuis le contexte nommé "docs" pour construire la documentation
RUN --mount=from=docs,target=/app/docs \
    make manpages

Cas d'usage pour les contextes nommés

Utiliser des contextes nommés permet une plus grande flexibilité et efficacité lors de la construction d'images Docker. Voici quelques scénarios où utiliser des contextes nommés peut être utile :

Exemple : combiner des sources locales et distantes

Vous pouvez définir des contextes nommés séparés pour différents types de sources. Par exemple, considérez un projet où le code source de l'application est local, mais les scripts de déploiement sont stockés dans un dépôt Git :

$ docker build --build-context scripts=https://github.com/user/deployment-scripts.git .

Dans le Dockerfile, vous pouvez utiliser ces contextes indépendamment :

# syntax=docker/dockerfile:1
FROM alpine:latest

# Copier le code de l'application depuis le contexte principal
COPY . /opt/app

# Exécuter les scripts de déploiement en utilisant le contexte "scripts" distant
RUN --mount=from=scripts,target=/scripts /scripts/main.sh

Exemple : builds dynamiques avec des dépendances personnalisées

Dans certains scénarios, vous pourriez avoir besoin d'injecter dynamiquement des fichiers de configuration ou des dépendances dans le build depuis des sources externes. Les contextes nommés rendent ceci simple en vous permettant de monter différentes configurations sans modifier le contexte de build par défaut.

$ docker build --build-context config=./configs/prod .

Exemple de Dockerfile :

# syntax=docker/dockerfile:1
FROM nginx:alpine

# Utiliser le contexte "config" pour les configurations spécifiques à l'environnement
COPY --from=config nginx.conf /etc/nginx/nginx.conf

Exemple : épingler ou remplacer des images

Vous pouvez référencer des contextes nommés dans un Dockerfile de la même façon que vous pouvez référencer une image. Cela signifie que vous pouvez changer une référence d'image dans votre Dockerfile en la remplaçant par un contexte nommé. Par exemple, étant donné le Dockerfile suivant :

FROM alpine:3.21

Si vous voulez forcer la référence d'image à résoudre vers une version différente, sans changer le Dockerfile, vous pouvez passer un contexte avec le même nom au build. Par exemple :

docker buildx build --build-context alpine:3.21=docker-image://alpine:edge .

Le préfixe docker-image:// marque le contexte comme une référence d'image. La référence peut être une image locale ou une image dans votre registre.

Contextes nommés avec Bake

Bake est un outil intégré dans docker build qui vous permet de gérer votre configuration de build avec un fichier de configuration. Bake prend entièrement en charge les contextes nommés.

Pour définir des contextes nommés dans un fichier Bake :

docker-bake.hcl
target "app" {
  contexts = {
    docs = "./docs"
  }
}

Ceci est équivalent à l'invocation CLI suivante :

$ docker build --build-context docs=./docs .

Lier des cibles avec des contextes nommés

En plus de rendre les builds complexes plus gérables, Bake fournit également des fonctionnalités supplémentaires en plus de ce que vous pouvez faire avec docker build en CLI. Vous pouvez utiliser des contextes nommés pour créer des pipelines de build, où une cible dépend de et construit par-dessus une autre. Par exemple, considérez une configuration Docker build où vous avez deux Dockerfiles :

  • base.Dockerfile : pour construire une image de base
  • app.Dockerfile : pour construire une image d'application

Le app.Dockerfile utilise l'image produite par base.Dockerfile comme son image de base :

app.Dockerfile
FROM mybaseimage

Normalement, vous devriez construire l'image de base en premier, puis soit la charger dans le magasin d'images local de Docker Engine ou la pousser vers un registre. Avec Bake, vous pouvez référencer d'autres cibles directement, créant une dépendance entre la cible app et la cible base.

docker-bake.hcl
target "base" {
  dockerfile = "base.Dockerfile"
}

target "app" {
  dockerfile = "app.Dockerfile"
  contexts = {
    # le préfixe target: indique que 'base' est une cible Bake
    mybaseimage = "target:base"
  }
}

Avec cette configuration, les références à mybaseimage dans app.Dockerfile utilisent les résultats de la construction de la cible base. Construire la cible app déclenchera également une reconstruction de mybaseimage, si nécessaire :

$ docker buildx bake app

Lecture complémentaire

Pour plus d'informations sur le travail avec les contextes nommés, voir :