Comment utiliser plusieurs contextes de construction Docker pour rationaliser l'assemblage d'images
Agence web » Actualités du digital » Comment utiliser plusieurs contextes de construction Docker pour rationaliser l’assemblage d’images

Comment utiliser plusieurs contextes de construction Docker pour rationaliser l’assemblage d’images

Le concept de Docker de « contexte de construction » est l’une de ses caractéristiques les plus restrictives et les plus mal comprises. Le contexte de construction définit les fichiers et dossiers locaux que vous pouvez référencer dans votre Dockerfile. Le contenu en dehors de celui-ci ne peut pas être utilisé, ce qui entrave souvent les procédures de construction complexes.

BuildKit v0.8 améliore cette situation en vous permettant d’utiliser plusieurs contextes avec chaque build que vous effectuez. Cela facilite le référencement de fichiers qui peuvent résider dans des emplacements complètement séparés, comme un fichier dans votre répertoire de travail et une dépendance à une URL distante.

Dans cet article, nous expliquerons pourquoi plusieurs contextes de génération sont utiles et comment vous pouvez les utiliser avec la dernière version de Docker CLI. Récapitulons d’abord ce qu’est le contexte de construction et pourquoi tant de personnes ont rencontré des problèmes dans le passé.

Objectif du contexte de génération

Docker est basé sur un démon. Le processus qui exécute vos versions d’image est indépendant du processus CLI qui émet la commande. Le démon peut être situé sur un hôte distant qui ne peut pas accéder directement au système de fichiers de votre machine.

Le contexte de génération fait référence aux fichiers qui sont transférés au démon Docker lorsqu’une génération se produit. C’est pourquoi seul le contenu du contexte peut être référencé par votre Dockerfile.

Il est courant de courir docker build avec . comme argument, ce qui fait de votre répertoire de travail le contexte de construction :

docker build -t my-website:latest .

Cela permet des références à n’importe quel chemin à l’intérieur de votre répertoire de travail :

FROM httpd:latest
COPY index.html /var/www/html/index.html

Vous ne pouvez pas tendre la main pour copier quoi que ce soit au dessus le répertoire de travail dans votre système de fichiers :

FROM httpd:latest
COPY index.html /var/www/html/index.html
COPY ../company-css/company.css /var/www/html/company.css

Chaque fichier dont vous avez besoin dans votre image de conteneur doit exister dans un répertoire unique que vous pouvez utiliser comme contexte de génération. Cela peut être problématique dans des situations comme celle illustrée ci-dessus, où vous souhaitez extraire des dépendances à partir de sources qui ne figurent pas dans l’arborescence de votre projet.

Utilisation de plusieurs contextes de génération

Plusieurs contextes de construction sont désormais pris en charge dans BuildKit v0.8 et versions ultérieures lorsque vous optez pour la syntaxe Dockerfile v1.4. Ces versions sont livrées avec la CLI Docker à partir de la version 20.10.13. Vous devriez pouvoir les utiliser aujourd’hui si vous utilisez la dernière version de Docker.

Vous devez créer votre image avec BuildKit pour utiliser plusieurs contextes. Ils ne sont pas pris en charge par l’ancien constructeur. Utilisez le docker buildx build commande au lieu de simple docker build:

$ docker buildx build -t my-website:latest .

Vous pouvez maintenant utiliser le --build-context flag pour définir plusieurs contextes de construction nommés :

$ docker buildx build -t my-website:latest . 
    --build-context company-css=../company-css 
    --build-context company-js=../company-js 

Ajustez votre Dockerfile pour référencer le contenu de ces contextes :

#syntax=docker/dockerfile:1.4
FROM httpd:latest
COPY index.html /var/www/html/index.html
COPY --from=company-css /company.css /var/www/html/company.css
COPY --from=company-js /company.js /var/www/html/company.js

Cela illustre comment vous pouvez copier des fichiers et des dossiers qui se trouvent en dehors de votre contexte de construction principal, quelle que soit leur position dans l’arborescence de votre système de fichiers.

La déclaration de syntaxe Dockerfile v1.4 est requise pour activer la prise en charge de la fonctionnalité. Vous pouvez ensuite utiliser le --from options avec ADD et COPY instructions pour extraire des fichiers à partir de contextes de construction nommés, de la même manière que pour référencer une ressource dans une étape de construction antérieure.

Commande prioritaire

Plusieurs contextes de construction modifient l’ordre de résolution des ressources pour le --from drapeau. Docker correspondra maintenant à la clé que vous fournissez (--from=key) en suivant la procédure suivante :

  • Recherchez un ensemble de contextes de génération nommé avec le --build-context drapeau.
  • Recherchez une étape de construction antérieure créée avec FROM my-image:latest AS stage-name.
  • Créez une nouvelle étape de construction en ligne en utilisant la clé donnée comme image de l’étape.

Cela signifie que vous pouvez utiliser des contextes nommés pour remplacer les dépendances distantes définies à l’aide des étapes de génération.

Considérez cet exemple :

#syntax=docker/dockerfile:1.4
FROM my-org/company-scss:latest AS css
RUN sass company.scss company.css

FROM httpd:latest
COPY index.html /var/www/html/index.html
COPY --from=css /company.css /var/www/html/company.css

Cette image Docker extrait certaines ressources distantes d’une autre image Docker partagée. Cela peut créer des difficultés lorsque vous testez votre projet – il peut y avoir un bogue dans la dépendance que vous souhaitez corriger rapidement.

Les contextes de génération nommés vous permettent de remplacer css nom de scène pour fournir un fichier local à la place :

$ docker buildx build -t my-website:latest . --build-context css=css/

Cela copiera votre répertoire de travail css/company.css fichier dans l’image finale, au lieu de la version fournie par le my-org/company-scss:latest dépendance.

L’ordre de résolution signifie que des remplacements peuvent être appliqués même si votre image n’utilise pas d’étapes de construction nommées. En définissant un contexte de construction avec le même nom qu’une image, votre Dockerfile extraira le contenu de ce contexte, au lieu de l’image de registre d’origine.

$ docker buildx build -t my-website:latest . --build-context my-org/company-scss:latest=css/

URL distantes

Les contextes de construction nommés prennent en charge toutes les sources qui docker build déjà accepté :

  • --build-context my-context=../local/path – Un chemin dans votre système de fichiers.
  • --build-context my-context=https://github.com/user/repo.git – Un référentiel Git distant.
  • --build-context my-context=https://example.com/data.tar – Une archive distante fournie par un serveur HTTP.
  • --build-context my-context=docker-image://busybox:latest – Le contenu d’une autre image Docker.

Les sources distantes simplifient davantage les remplacements de dépendance. Vous pouvez pointer directement vers un référentiel Git forké ou vers une autre balise d’image Docker, tout en laissant votre Dockerfile inchangé.

Montage de fichiers à partir d’un contexte de génération

Les contextes de construction nommés fonctionnent avec RUN consignes aussi. Vous pouvez utiliser --mount=from pour exécuter un exécutable à partir d’un autre contexte de construction.

#syntax=docker/dockerfile:1.4
RUN --mount=from=name-of-build-context demo-executable

Cela monte le fichier sans le copier dans la couche actuelle, ce qui contribue à améliorer les performances. demo-executable n’existera pas dans l’image finale.

Reconstruction précise des images

Un autre cas d’utilisation des contextes de construction nommés concerne la reconstruction d’images à l’avenir. Dockerfiles avec des instructions comme FROM alpine:3.15 ne sont pas totalement reproductibles. Les balises d’image sont mutable donc alpine:3.15 peut contenir un contenu différent à l’avenir, après la publication d’un nouveau correctif. Cela signifie que les images reconstruites ne sont pas garanties de produire les mêmes calques que leurs versions d’origine.

Vous pouvez résoudre ce problème en inspectant les métadonnées de la première compilation pour découvrir l’image de base exacte qui a été utilisée :

$ docker buildx imagetools inspect --format '{{json .BuildInfo}}' my-image:latest
{
    ...
    "sources": [
        {
            "type": "docker-image",
            "ref": "docker.io/library/alpine:3.15",
            "pin": "sha256:4edbd2beb5f78b1014028f4fbb99f3237d9561100b6881aabbf5acce2c4f9454"
        }
    ]
    ...
}

Vous pouvez maintenant définir un contexte de construction nommé appelé alpine:3.15 qui pointe vers la version exacte qui a été précédemment utilisée :

$ docker buildx build -t my-image:latest . --build-context alpine:3.15=docker-image://alpine3.15@4edbd2beb5f78b1014028f4fbb99f3237d9561100b6881aabbf5acce2c4f9454

Cela simplifie la création d’une reconstruction précise d’une image précédemment créée, sans avoir à modifier son Dockerfile.

Conclusion

Plusieurs contextes de construction vous offrent plus d’options pour organiser des Dockerfiles complexes et des arborescences de répertoires de projets. Ils résolvent les problèmes d’utilisabilité de longue date que vous pouvez rencontrer avec un contexte de construction unique.

Les contextes de construction nommés vous permettent d’inclure des dépendances hors de l’arborescence et d’effectuer des remplacements ad hoc. Ils fonctionnent bien avec les étapes de construction nommées existantes de Docker. La combinaison des deux fonctionnalités vous aide à créer des Dockerfiles modulaires qui peuvent être personnalisés au moment de la construction.

Vous pouvez commencer avec plusieurs contextes de construction dès aujourd’hui en mettant à jour vers Docker 20.10.13 ou une version plus récente et en utilisant docker buildx pour créer vos images. Des distributions BuildKit autonomes sont également disponibles lorsque vous ne souhaitez pas installer l’intégralité de la CLI Docker.

★★★★★