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

Construire des images dépendantes

Requires: Docker Compose 2.22.0 and later

Pour réduire le temps de push/pull et le poids des images, une pratique courante pour les applications Compose est de faire en sorte que les services partagent le plus possible de couches de base. Vous sélectionnerez généralement la même image de base du système d'exploitation pour tous les services. Mais vous pouvez également aller plus loin en partageant des couches d'image lorsque vos images partagent les mêmes paquets système. Le défi à relever est alors d'éviter de répéter exactement la même instruction Dockerfile dans tous les services.

Pour illustration, cette page suppose que vous voulez que tous vos services soient construits avec une image de base alpine et installer le paquet système openssl.

Dockerfile multi-étapes

L'approche recommandée est de regrouper la déclaration partagée dans un seul Dockerfile, et d'utiliser les fonctionnalités multi-étapes pour que les images de service soient construites à partir de cette déclaration partagée.

Dockerfile :

FROM alpine as base
RUN /bin/sh -c apk add --update --no-cache openssl

FROM base as service_a
# construire le service a
...

FROM base as service_b
# construire le service b
...

Fichier Compose :

services:
  a:
     build:
       target: service_a
  b:
     build:
       target: service_b

Utiliser l'image d'un autre service comme image de base

Un modèle populaire est de réutiliser l'image d'un service comme image de base dans un autre service. Comme Compose n'analyse pas le Dockerfile, il ne peut pas détecter automatiquement cette dépendance entre les services pour ordonner correctement l'exécution de la construction.

a.Dockerfile :

FROM alpine
RUN /bin/sh -c apk add --update --no-cache openssl

b.Dockerfile :

FROM service_a
# construire le service b

Fichier Compose :

services:
  a:
     image: service_a 
     build:
       dockerfile: a.Dockerfile
  b:
     image: service_b
     build:
       dockerfile: b.Dockerfile

L'ancien Docker Compose v1 construisait les images séquentiellement, ce qui rendait ce modèle utilisable prêt à l'emploi. Compose v2 utilise BuildKit pour optimiser les constructions et construire les images en parallèle et nécessite une déclaration explicite.

L'approche recommandée est de déclarer l'image de base dépendante comme un contexte de construction supplémentaire :

Fichier Compose :

services:
  a:
     image: service_a
     build: 
       dockerfile: a.Dockerfile
  b:
     image: service_b
     build:
       dockerfile: b.Dockerfile
       additional_contexts:
         # `FROM service_a` sera résolu comme une dépendance sur le service "a" qui doit être construit en premier
         service_a: "service:a"

Avec l'attribut additional_contexts, vous pouvez référencer une image construite par un autre service sans avoir besoin de la nommer explicitement :

b.Dockerfile :


FROM base_image  
# `base_image` ne résout pas vers une image réelle. Ceci est utilisé pour pointer vers un contexte supplémentaire nommé

# construire le service b

Fichier Compose :

services:
  a:
     build: 
       dockerfile: a.Dockerfile
       # l'image construite sera taguée <nom_projet>_a
  b:
     build:
       dockerfile: b.Dockerfile
       additional_contexts:
         # `FROM base_image` sera résolu comme une dépendance sur le service "a" qui doit être construit en premier
         base_image: "service:a"

Construire avec Bake

Utiliser Bake vous permet de passer la définition de construction complète pour tous les services et d'orchestrer l'exécution de la construction de la manière la plus efficace.

Pour activer cette fonctionnalité, exécutez Compose avec la variable COMPOSE_BAKE=true définie dans votre environnement.

$ COMPOSE_BAKE=true docker compose build
[+] Building 0.0s (0/1)                                                         
 => [internal] load local bake definitions                                 0.0s
...
[+] Building 2/2 manifest list sha256:4bd2e88a262a02ddef525c381a5bdb08c83  0.0s
 ✔ service_b  Built                                                        0.7s 
 ✔ service_a  Built    

Bake peut également être sélectionné comme constructeur par défaut en éditant votre fichier de configuration $HOME/.docker/config.json :

{
  ...
  "plugins": {
    "compose": {
      "build": "bake"
    }
  }
  ...
}