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
CMD
peut ê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
CMD
peut avoir une forme exécutable. Si l'instruction n'inclut pas la référence au fichier exécutable, alors l'instruction ENTRYPOINT
doit être présente dans le fichier. Dans ce cas, ces deux instructions doivent être au JSON
. - Les arguments de ligne de commande passés à
docker run
remplacent les arguments fournis par l'instruction CMD
dans 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
WORKDIR
plutôt que de naviguer dans le système de fichiers à l'aide des commandes cd
dans le Dockerfile. - L'instruction
WORKDIR
cré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-.
