contexte de construction pour l'image du docker très grand

142

J'ai créé quelques répertoires différents sur ma machine hôte alors que j'essaie d'en apprendre davantage sur Docker juste pour garder mes fichiers docker organisés. Mon Dockerfile que je viens d'exécuter ressemble à ceci:

FROM crystal/centos
MAINTAINER crystal

ADD ./rpms/test.rpm ./rpms/ 
RUN yum -y --nogpgcheck localinstall /rpms/test.rpm 

Mon régime réel n'est que de 1 Go. Mais quand j'essaye de le faire sudo docker build -t="crystal/test" ., j'envoie le contexte de construction au démon Docker 3,5 Go. Y a-t-il autre chose dont je ne suis pas au courant alors que vous continuez à créer des images Docker? Ma mémoire s'accumule-t-elle à mesure que je construis plus d'images dans mes autres répertoires sur ma machine hôte?

Cristal
la source
2
Le contexte de construction correspond à tous les fichiers / répertoires du répertoire courant.
Nabin
Conservez uniquement les fichiers dont vous avez besoin pour la construction dans ce répertoire. Autrement dit, le Dockerfile et tous les fichiers / répertoires locaux copiés / ajoutés à l'image de construction dans le Dockerfile. Aussi, utilisez.dockerignore
Vishrant

Réponses:

266

Le client Docker envoie l'intégralité du «contexte de construction» au démon Docker. Ce contexte de construction (par défaut) est le répertoire entier dans lequel se Dockerfiletrouve (donc, l' rpmsarborescence entière ).

Vous pouvez configurer un .dockerignorefichier pour que Docker ignore certains fichiers. Vous voudrez peut-être l'expérimenter.

Vous pouvez également déplacer votre rpmsdossier d'un niveau de répertoire au-dessus de votre Dockerfile, et uniquement le lien symbolique test.rpmdans le Dockerfilerépertoire s.


Comme de nombreux utilisateurs l'ont souligné dans les commentaires, il faut ajouter le .gitdossier au dossier.dockerignore qui était à l'origine d'une différence de 150 Mo -> 5 Go dans mon cas.

Thomas Orozco
la source
4
Malheureusement, il semble que la liaison symbolique ne soit pas possible dans ce cas car la ADDcommande ne suit pas les liens symboliques pendant une construction. Voir: github.com/docker/docker/issues/1676
JimmidyJoo
5
bouée de sauvetage! Développeurs Rails: assurez-vous d'en ajouter tmp logà .dockerignore+ d'autres personnalisés
équivalent du
7
n'oubliez pas d'ajouter le dossier .git au fichier .dockerignore (en supposant que vous utilisez git)
dsncode
8
Oui, le .gitdossier est inclus par défaut - cela m'a définitivement surpris.
Paul Suart
1
Quel est exactement le "contexte de construction"? J'ai essayé de rechercher ces fichiers à l'aide de la commande docker build RUN, mais je ne vois pas les fichiers dans mon dossier Dockerfile dans le système de fichiers docker (pendant la construction.) Quelqu'un peut-il me donner un exemple simple en quoi le contexte de construction est utile?
Patrick
52

Mise à jour 2019

À partir de Docker v18.06, il existe une option pour utiliser un nouveau générateur d'images appelé Build Kit .

Il est pré-fourni avec le Docker, pas besoin d'installer quoi que ce soit. Il est rétrocompatible avec la Dockerfilesyntaxe, pas besoin de changer le Dockerfile.

Ancienne version de Docker vs nouveau Docker BuildKit

Voici un exemple de construction d'une image avec un énorme fichier inutilisé dans le répertoire de construction:

Ancienne version de Docker:

$ time docker image build --no-cache .
Sending build context to Docker daemon  4.315GB
[...]
Successfully built c9ec5d33e12e

real    0m51.035s
user    0m7.189s
sys 0m10.712s

Nouveau Docker BuildKit:

$ time DOCKER_BUILDKIT=1 docker image build --no-cache .
[+] Building 0.1s (5/5) FINISHED                                                
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 37B                                        0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 2B                                            0.0s
[...]
 => => writing image sha256:ba5bca3a525ac97573b2e1d3cb936ad50cf8129eedfa9  0.0s

real    0m0.166s
user    0m0.034s
sys 0m0.026s

Le seul changement est la DOCKER_BUILDKIT=1variable d'environnement, la différence de temps est énorme.

.dockerignore Fichier

Veuillez noter que le .dockerignorefichier est toujours valide et utile. Certaines Dockerfilecommandes comme COPY . .prendront toujours en compte les .dockerignorerègles. Mais les fichiers Dockerfileannexes dans le répertoire de construction (non référencés dans le ) ne sont plus copiés en tant que "contexte de construction" par le BuildKit.

Andriy Berestovskyy
la source
1
Il est important de noter que DOCKER_BUILDKIT n'est actuellement pas pris en charge pour les conteneurs Windows. (Linux uniquement, répertorié sous limitations: docs.docker.com/develop/develop-images/build_enhancements )
Vaccano
18

Je l'ai corrigé en déplaçant mon Dockerfile et docker-compose.yml dans un sous-dossier et cela a très bien fonctionné. Apparemment, docker envoie le dossier actuel au démon et mon dossier était de 9 concerts.

Emad
la source
4
Cette méthode donne un chemin interdit: en dehors de l'erreur de contexte de construction si un fichier d'un répertoire parent est copié, une solution pour cela?
Kitwradr
8

Si vous avez un .dockerignorefichier et que le contexte de construction est toujours volumineux, vous pouvez vérifier ce qui est envoyé au contexte de construction du docker à l'aide de Silver Searcher :

ag --path-to-ignore .dockerignore --files-with-matches

Notez que certains **modèles peuvent ne pas fonctionner correctement.

Consultez ce numéro de Github pour des commentaires supplémentaires: https://github.com/moby/moby/issues/16056

Luís Bianchin
la source
4

Dans mon cas, c'était quand j'exécute avec de mauvais -farguments - sans chemin vers le répertoire où se trouve Dockerfile

docker build --no-cache -t nginx5 -f /home/DF/Dockerfile /home/DF/ - droite

docker build --no-cache -t nginx5 -f /home/DF/Dockerfile - faux

FreeStyler
la source
1

Si vous voulez avoir le contrôle total de votre contexte de construction, vous pouvez également créer le conteneur complètement sans aucun contexte ni COPYdonnées pertinentes dans le conteneur par la suite.

docker build - < Dockerfile

Un inconvénient serait qu'avec cette approche, vous ne pouvez que des ADDéléments du fichier docker référençant à une URL distante, et non des fichiers de votre hôte local.

Voir https://docs.docker.com/engine/reference/commandline/build/#build-with--

Christian.D
la source
0

J'ai eu le même problème que FreeStyler. Cependant, je construisais à partir d'un répertoire à partir de mon contexte. Ainsi, les arguments -f étaient corrects, le contexte était incorrect.

project 
|
-------docker-dir 

Construire à partir du docker-dir ce qui suit était bien

docker build -t br_base:0.1 . 

La construction à partir du répertoire-dock a changé le contexte de construction. Par conséquent, j'avais besoin de changer le contexte dans la commande. Le contexte est donné par le '.' dans la commande ci-dessus.

La nouvelle commande du répertoire du projet doit être

docker build -t br_base:0.1 ./base

Le contexte ici est donné par le './base'

BravoRomeo23
la source
0

si vous créez une image et recevez un message envoyant un contexte de construction au démon docker qui prend du temps à copier,

puis ajoutez le fichier .dockerignore . il doit inclure les fichiers ou le répertoire qui n'ont pas besoin d'être copiés.

Pandit shashikant
la source
0

Pour NodeJS Application, ajoutez un .dockerignorefichier à votre répertoire de projet racine et à l'intérieur du .dockerignorefichier, ajoutez ce qui suit

node_modules
dist
Bernard Nongpoh
la source