Dans la traduction de la troisième partie de la série Docker, nous continuerons à nous inspirer des pâtisseries, à savoir les bagels. Notre sujet principal aujourd'hui sera de travailler avec Dockerfiles. Nous analyserons les instructions utilisées dans ces fichiers.
→ 
Partie 1: les bases→ 
Partie 2: termes et concepts→ 
Partie 3: Fichiers Dockerfile→ 
Partie 4: réduire la taille des images et accélérer leur assemblage→ 
Partie 5: équipes→ 
Partie 6: travailler avec des donnéesLes bagels sont des instructions dans un Dockerfile.Images Docker
Rappelons qu'un conteneur Docker est une image Docker qui prend vie. Il s'agit d'un système d'exploitation autonome dans lequel il n'y a que le code d'application et le plus nécessaire.
Les images Docker sont le résultat du processus de génération et les conteneurs Docker exécutent des images. Au cœur même de Docker se trouvent les Dockerfiles. Des fichiers comme celui-ci indiquent à Docker comment assembler les images à partir desquelles les conteneurs sont créés.
Chaque image Docker possède un fichier appelé Dockerfile. Son nom est écrit de cette façon - sans extension. Lorsque vous exécutez la 
docker build pour créer une nouvelle image, il est supposé que le Dockerfile se trouve dans le répertoire de travail actuel. Si ce fichier se trouve à un autre endroit, son emplacement peut être spécifié à l'aide de l'indicateur 
-f .
Les conteneurs, comme nous l'avons découvert dans le premier matériau de cette série, sont constitués de couches. Chaque couche, à l'exception de la dernière, située au-dessus de toutes les autres, est en lecture seule. Dockerfile indique au système Docker quelles couches et dans quel ordre ajouter à l'image.
Chaque couche, en fait, n'est qu'un fichier qui décrit le changement de l'état de l'image par rapport à l'état dans lequel elle se trouvait après l'ajout de la couche précédente. Sur Unix, d'ailleurs, presque tout est un 
fichier .
Une image de base est le calque (ou les calques) source de l'image en cours de création. L'image de base est également appelée image parente.
L'image de base est l'endroit où l'image Docker commence.Lorsqu'une image est téléchargée d'un référentiel distant vers un ordinateur local, seules les couches qui ne sont pas disponibles sur cet ordinateur sont physiquement téléchargées. Docker vise à économiser de l'espace et du temps en réutilisant les couches existantes.
Fichiers Dockerfile
Les Dockerfiles contiennent des instructions pour créer une image. En majuscules, les lignes de ce fichier commencent. Suivre les instructions sont leurs arguments. Les instructions, lors de la construction de l'image, sont traitées de haut en bas. Voici à quoi ça ressemble:
 FROM ubuntu:18.04 COPY . /app 
Les calques de l'image finale sont créés uniquement par les instructions 
FROM , 
RUN , 
COPY et 
ADD . D'autres instructions définissent quelque chose, décrivent des métadonnées ou indiquent à Docker que vous devez faire quelque chose pendant l'exécution du conteneur, par exemple, ouvrir un port ou exécuter une commande.
Ici, nous partons de l'hypothèse qu'une image Docker basée sur un système d'exploitation de type Unix est utilisée. Bien sûr, ici, vous pouvez également utiliser une image basée sur Windows, mais l'utilisation de Windows est une pratique moins courante, travailler avec de telles images est plus difficile. Par conséquent, si vous en avez l'occasion, utilisez Unix.
Pour commencer, voici une liste d'instructions Dockerfile avec de brefs commentaires.
Douzaine d'instructions Dockerfile
- FROM- définit l'image de base (parent).
- LABEL- décrit les métadonnées. Par exemple, des informations sur qui a créé et gère l'image.
- ENV- définit les variables d'environnement persistantes.
- RUN- exécute une commande et crée une couche d'image. Utilisé pour installer des packages dans un conteneur.
- COPY- copie les fichiers et dossiers dans le conteneur.
- ADD- copie les fichiers et les dossiers dans un conteneur, peut décompresser les fichiers .tar locaux.
- CMD- décrit une commande avec des arguments qui doit être exécutée au lancement du conteneur. Les arguments peuvent être remplacés au démarrage du conteneur. Un fichier ne peut contenir qu'une seule instruction- CMD.
- WORKDIR- définit le répertoire de travail pour l'instruction suivante.
- ARG- définit les variables pour passer Docker lors de la construction de l'image.
- ENTRYPOINT- Fournit une commande avec des arguments à invoquer pendant l'exécution du conteneur. Les arguments ne sont pas remplacés.
- EXPOSE- indique la nécessité d'ouvrir le port.
- VOLUME- crée un point de montage pour travailler avec un stockage persistant.
Parlons maintenant de ces instructions.
Instructions et exemples d'utilisation
DockSimple Dockerfile
Dockerfile peut être extrêmement simple et court. Par exemple - comme ceci:
 FROM ubuntu:18.04 
▍De l'instruction
Le Dockerfile doit commencer par une instruction 
FROM ou par une instruction 
ARG suivie d'une instruction 
FROM .
Le mot clé 
FROM indique à Docker d'utiliser une image de base qui correspond au nom et à la balise fournis lors de la création de l'image. De plus, l'image de base est également appelée 
image parente .
Dans cet exemple, l'image de base est stockée dans le référentiel 
ubuntu . Ubuntu est le nom du référentiel Docker officiel, qui fournit la version de base de la célèbre famille de systèmes d'exploitation Linux appelée Ubuntu.
Veuillez noter que le Dockerfile en question comprend une balise 
18.04 qui spécifie l'image de base dont nous avons besoin. C'est cette image qui sera chargée lors de la construction de notre image. Si la balise n'est pas incluse dans l'instruction, Docker part de l'hypothèse que la dernière image du référentiel est requise. Afin d'exprimer plus clairement leurs intentions, il est recommandé que l'auteur du Dockerfile indique de quelle image il a besoin.
Lorsque le Dockerfile ci-dessus est utilisé sur la machine locale pour créer l'image pour la première fois, Docker charge les couches définies par l'image 
ubuntu . Ils peuvent être imaginés superposés les uns aux autres. Chaque couche suivante est un fichier décrivant les différences de l'image par rapport à l'état dans lequel elle se trouvait après y avoir ajouté la couche précédente.
Lorsque vous créez un conteneur, un calque dans lequel vous pouvez apporter des modifications est ajouté au-dessus de tous les autres calques. Les données des couches restantes peuvent uniquement être lues.
Structure du conteneur (extraite de la documentation )Docker, par souci d'efficacité, utilise une stratégie de copie sur écriture. Si le calque de l'image existe au niveau précédent et qu'un calque doit en lire des données, Docker utilise le fichier existant. Vous n'avez rien à télécharger.
Lorsque l'image est exécutée, si le calque doit être modifié au moyen du conteneur, le fichier correspondant est copié dans le calque mutable le plus haut. Pour en savoir plus sur la stratégie de copie sur écriture, consultez 
ce matériel dans la documentation Docker.
Nous continuons la discussion des instructions utilisées dans le Dockerfile, en donnant un exemple d'un tel fichier avec une structure plus complexe.
DockFichier docker plus sophistiqué
Bien que le Dockerfile que nous venons de passer en revue se soit avéré net et compréhensible, il est trop simple, il n'utilise qu'une seule instruction. De plus, aucune instruction n'est appelée lors de l'exécution du conteneur. Jetez un oeil à un autre fichier qui recueille une petite image. Il dispose de mécanismes qui déterminent les commandes qui sont appelées lors de l'exécution du conteneur.
 FROM python:3.7.2-alpine3.8 LABEL maintainer="jeffmshale@gmail.com" ENV ADMIN="jeff" RUN apk update && apk upgrade && apk add bash COPY . ./app ADD https://raw.githubusercontent.com/discdiver/pachy-vid/master/sample_vids/vid1.mp4 \ /my_app_directory RUN ["mkdir", "/a_directory"] CMD ["python", "./my_script.py"] 
À première vue, ce fichier peut sembler plutôt compliqué. Par conséquent, traitons-le avec lui.
La base de cette image est l'image Python officielle avec la balise 3.7.2-alpine3.8. Après avoir analysé 
ce code, vous pouvez voir que cette image de base inclut Linux, Python et, dans l'ensemble, cela se limite à sa composition. Les images Alpine OS sont très populaires dans le monde Docker. Le fait qu'ils sont de petite taille, haute vitesse et sécurité. Cependant, les images Alpine ne diffèrent pas par les larges capacités typiques des systèmes d'exploitation conventionnels. Par conséquent, afin de collecter quelque chose d'utile sur la base d'une telle image, le créateur de l'image doit installer les packages dont il a besoin.
▍Instruction LABEL
BalisesL' 
instruction LABEL (étiquette) vous permet d'ajouter des métadonnées à l'image. Dans le cas du fichier en cours d'examen, il contient les coordonnées du créateur de l'image. La déclaration d'étiquettes ne ralentit pas le processus d'assemblage d'image et n'augmente pas sa taille. Ils ne contiennent que des informations utiles sur l'image Docker, il est donc recommandé de les inclure dans le fichier. Des détails sur l'utilisation des métadonnées dans le Dockerfile peuvent être trouvés 
ici .
▍Inv instruction
L'environnementL'instruction 
ENV vous permet de définir des variables d'environnement constantes qui seront disponibles dans le conteneur lors de son exécution. Dans l'exemple précédent, après avoir créé le conteneur, vous pouvez utiliser la variable 
ADMIN .
L'instruction 
ENV est bien adaptée pour définir des constantes. Si vous utilisez plusieurs fois une certaine valeur dans le Dockerfile, par exemple, lorsque vous décrivez les commandes qui s'exécutent dans le conteneur, et que vous pensez qu'un jour vous devrez peut-être la changer en une autre, il est logique de l'écrire dans une constante similaire.
Il convient de noter que dans les fichiers Dockerfile, il existe souvent différentes manières de résoudre les mêmes problèmes. Quelle est exactement la question à utiliser, dont la décision est influencée par la volonté de se conformer aux méthodes de travail adoptées dans l'environnement Docker, afin d'assurer la transparence de la solution et ses hautes performances. Par exemple, les 
ENTRYPOINT RUN , 
CMD et 
ENTRYPOINT des objectifs différents, mais elles sont toutes utilisées pour exécuter des commandes.
Instruction UNRUN
Instruction RUNL'instruction 
RUN vous permet de créer un calque lors de la création de l'image. Après son exécution, un nouveau calque est ajouté à l'image, son état est fixe. L'instruction 
RUN est souvent utilisée pour installer des packages supplémentaires dans les images. Dans l'exemple précédent, l'instruction 
RUN apk update && apk upgrade indique à Docker que le système doit mettre à jour les packages à partir de l'image de base. Après ces deux commandes se trouve la commande 
&& apk add bash , indiquant que bash doit être installé dans l'image.
Ce qui ressemble à 
apk dans les équipes est une abréviation pour 
Alpine Linux package manager . Si vous utilisez l'image de base d'un autre système d'exploitation de la famille Linux, alors, par exemple, lorsque vous utilisez Ubuntu, vous pouvez avoir besoin d'une commande de la forme 
RUN apt-get pour installer les packages. Plus tard, nous parlerons d'autres façons d'installer des packages.
L'instruction 
RUN et des instructions similaires, telles que 
CMD et 
ENTRYPOINT , peuvent être utilisées soit sous la forme 
ENTRYPOINT , soit sous forme de shell. Le formulaire exec utilise une syntaxe qui ressemble à la description d'un tableau JSON. Par exemple, cela pourrait ressembler à ceci: 
RUN ["my_executable", "my_first_param1", "my_second_param2"] .
Dans l'exemple précédent, nous avons utilisé la forme shell de l'instruction RUN comme suit: 
RUN apk update && apk upgrade && apk add bash .
Plus tard dans notre Dockerfile, nous avons utilisé la forme exec de l'instruction 
RUN , sous la forme 
RUN ["mkdir", "/a_directory"] pour créer un répertoire. Dans le même temps, en utilisant les instructions de ce formulaire, vous devez vous rappeler la nécessité de formater les chaînes avec des guillemets doubles, comme c'est la coutume au format JSON.
▍ COPIE D'INSTRUCTION
Instruction COPYL'instruction 
COPY est présentée dans notre fichier comme ceci: 
COPY . ./app COPY . ./app . Elle indique à Docker qu'elle doit extraire des fichiers et des dossiers du contexte local de l'assembly et les ajouter au répertoire de travail actuel de l'image. Si le répertoire de destination n'existe pas, cette instruction le créera.
▍Instruction AJOUTER
L'instruction 
ADD vous permet de résoudre les mêmes problèmes que 
COPY , mais quelques 
COPY utilisation supplémentaires lui sont associés. Ainsi, en utilisant cette instruction, vous pouvez ajouter des fichiers téléchargés à partir de sources distantes dans le conteneur, ainsi que décompresser les fichiers .tar locaux.
Dans cet exemple, l'instruction 
ADD été utilisée pour copier un fichier accessible par URL dans le 
my_app_directory conteneur 
my_app_directory . Il convient de noter, cependant, que la 
documentation Docker ne recommande pas l'utilisation de tels fichiers obtenus par URL, car ils ne peuvent pas être supprimés et qu'ils augmentent la taille de l'image.
En outre, la 
documentation suggère, dans la mesure du possible, que vous 
COPY instruction 
COPY au lieu de l'instruction 
ADD pour rendre le Dockerfile plus facile à comprendre. Je suppose que l'équipe de développement Docker devrait combiner 
ADD et 
COPY en une seule instruction afin que ceux qui créent les images n'aient pas à se souvenir de trop d'instructions.
Notez que l'instruction 
ADD contient le caractère de saut de ligne - 
\ . Ces caractères sont utilisés pour améliorer la lisibilité des commandes longues en les divisant en plusieurs lignes.
▍ Instruction CMD
Instruction CMDL'instruction 
CMD fournit à Docker une commande à exécuter au démarrage du conteneur. Les résultats de cette commande ne sont pas ajoutés à l'image lors de son assemblage. Dans notre exemple, cette commande lance le script 
my_script.py au moment de l'exécution.
Voici autre chose que vous devez savoir sur l'instruction 
CMD :
- Une seule instruction CMDpeut être présente dans un Dockerfile. S'il y a plusieurs instructions de ce type dans le fichier, le système ignorera tout sauf la dernière.
- Une instruction CMDpeut avoir une forme exécutable. Si l'instruction n'inclut pas la référence au fichier exécutable, alors l'instructionENTRYPOINTdoit être présente dans le fichier. Dans ce cas, ces deux instructions doivent être auJSON.
- Les arguments de ligne de commande passés à docker runremplacent les arguments fournis par l'instructionCMDdans le Dockerfile.
DockUn Dockerfile encore plus complexe
Prenons un autre Dockerfile, dans lequel de nouvelles commandes seront utilisées.
 FROM python:3.7.2-alpine3.8 LABEL maintainer="jeffmshale@gmail.com" #   RUN apk add --update git #     WORKDIR /usr/src/my_app_directory #          COPY . . #       ARG my_var=my_default_value #  ,           ENTRYPOINT ["python", "./app/my_script.py", "my_var"] #   EXPOSE 8000 #      VOLUME /my_volume 
Dans cet exemple, entre autres choses, vous pouvez voir les commentaires commençant par le caractère 
# .
Dockerfile fait notamment l'installation de packages. Comme déjà mentionné, il existe différentes façons d'installer des packages à l'aide de l'instruction 
RUN .
Les packages dans l'image Alpine Docker peuvent être installés à l'aide d' 
apk . Pour cela, comme nous l'avons déjà dit, une commande de la forme 
RUN apk update && apk upgrade && apk add bash .
De plus, les packages Python dans l'image peuvent être installés à l'aide de 
pip , 
wheel et 
conda . Si nous ne parlons pas de Python, mais d'autres langages de programmation, alors d'autres gestionnaires de paquets peuvent être utilisés pour préparer les images correspondantes.
Dans le même temps, pour que l'installation soit possible, la couche sous-jacente doit fournir au gestionnaire de packages un gestionnaire de packages approprié. Par conséquent, si vous rencontrez des problèmes lors de l'installation de packages, assurez-vous que le gestionnaire de packages est installé avant d'essayer de l'utiliser.
Par exemple, vous pouvez utiliser l'instruction 
RUN dans un Dockerfile pour installer une liste de packages à l'aide de 
pip . Si vous faites cela, combinez toutes les commandes en une seule instruction et séparez-la avec des caractères de saut de ligne en utilisant le caractère 
\ . Grâce à cette approche, les fichiers seront nets et cela conduira à ajouter moins de couches à l'image que ce qui serait ajouté à l'aide de plusieurs instructions 
RUN .
De plus, vous pouvez faire différentes choses pour installer plusieurs packages. Vous pouvez les répertorier dans un fichier et transférer ce fichier vers le gestionnaire de packages à l'aide de 
RUN . Ces fichiers sont généralement appelés 
requirements.txt .
▍ Instruction WORKDIR
Répertoires de travailL'instruction 
WORKDIR vous permet de modifier le répertoire de travail du conteneur. Les 
ENTRYPOINT COPY , 
ADD , 
RUN , 
CMD et 
ENTRYPOINT qui suivent 
WORKDIR fonctionnent avec ce répertoire. Voici quelques fonctionnalités liées à cette instruction:
- Il est préférable de définir des chemins absolus vers des dossiers avec WORKDIRplutôt que de naviguer dans le système de fichiers à l'aide des commandescddans le Dockerfile.
- L'instruction WORKDIRcrée automatiquement un répertoire s'il n'existe pas.
- Vous pouvez utiliser plusieurs instructions WORKDIR. Si des instructions relatives sont fournies à ces instructions, chacune d'elles modifie le répertoire de travail actuel.
▍Guide ARG
L'instruction 
ARG vous permet de définir une variable dont la valeur peut être transmise de la ligne de commande à l'image lors de son assemblage. La valeur de la variable par défaut peut être représentée dans le Dockerfile. Par exemple: 
ARG my_var=my_default_value .
Contrairement aux variables 
ENV variables 
ARG ne sont pas disponibles au moment de l'exécution. Cependant, les variables 
ARG peuvent être utilisées pour définir les valeurs par défaut des variables 
ENV à partir de la ligne de commande lors de la création de l'image. Et les variables 
ENV seront déjà disponibles dans le conteneur lors de son exécution. Des détails sur cette technique de travail avec des variables peuvent être trouvés 
ici .
POINT D'ENTRÉE DE L'INSTRUCTION
Point de transition vers un endroitL' 
instruction ENTRYPOINT vous permet de spécifier une commande avec des arguments qui doivent être exécutés au démarrage du conteneur. Elle est similaire à la commande 
CMD , mais les paramètres spécifiés dans 
ENTRYPOINT ne sont pas remplacés si le conteneur est démarré avec des paramètres de ligne de commande.
Au lieu de cela, les arguments de ligne de commande passés dans les constructions du formulaire 
docker run my_image_name sont ajoutés aux arguments spécifiés par l' 
ENTRYPOINT . Par exemple, après avoir exécuté une commande du formulaire 
docker run my_image bash argument 
docker run my_image bash sera ajouté à la fin de la liste des arguments spécifiés par 
ENTRYPOINT . Lors de la préparation de votre Dockerfile, n'oubliez pas les 
ENTRYPOINT CMD ou 
ENTRYPOINT .
Il existe plusieurs recommandations dans la documentation de Docker concernant l'instruction, 
CMD ou 
ENTRYPOINT , à choisir comme outil pour exécuter des commandes au démarrage du conteneur:
- Si vous devez exécuter la même commande à chaque démarrage du conteneur, utilisez ENTRYPOINT.
- Si le conteneur sera utilisé comme application, utilisez ENTRYPOINT.
- Si vous savez que lorsque vous démarrez le conteneur, vous devez lui passer des arguments qui peuvent remplacer les arguments spécifiés dans le Dockerfile, utilisez CMD.
Dans notre exemple, l'utilisation de l'instruction 
ENTRYPOINT ["python", "my_script.py", "my_var"] oblige le conteneur, lorsqu'il démarre, à exécuter le script Python 
my_script.py avec l'argument 
my_var . La valeur représentée par 
my_var peut ensuite être utilisée dans le script en utilisant 
argparse . , Dockerfile 
my_var , , 
ARG . , , .
Docker exec- 
ENTRYPOINT : 
ENTRYPOINT ["executable", "param1", "param2"] .
▍ EXPOSE
EXPOSEEXPOSE , , . . , , , , , , .
( ) , 
docker run -p . 
-P ( 
P ), , 
EXPOSE .
▍ VOLUME
VOLUMEVOLUME , . .
Résumé
, Dockerfile. . , , 
USER , 
ONBUILD , 
STOPSIGNAL , 
SHELL HEALTHCHECK . 
Dockerfile.
, Dockerfile — Docker, , . , .
Chers lecteurs! Docker , , Docker-.
