Construir contexto para la imagen acoplable muy grande

142

He creado un par de directorios diferentes en mi máquina host mientras trato de aprender sobre Docker solo para mantener mis dockerfiles organizados. Mi Dockerfile que acabo de ejecutar se ve así:

FROM crystal/centos
MAINTAINER crystal

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

Mi rpm actual es de solo 1 GB. Pero cuando intento hacerlo sudo docker build -t="crystal/test" ., recibo el contexto de compilación para Docker daemon 3.5 GB. ¿Hay algo más de lo que no estoy al tanto mientras continúas creando imágenes de Docker? ¿Se está acumulando mi memoria a medida que construyo más imágenes en mis otros directorios en mi máquina host?

Cristal
fuente
2
El contexto de compilación son todos los archivos / directorios en el directorio actual.
Nabin
Mantenga solo los archivos que necesita para la compilación en este directorio. Es decir, el Dockerfile y cualquier archivo / directorio local copiado / agregado a la imagen de compilación en el Dockerfile. Además, haga uso de.dockerignore
Vishrant

Respuestas:

266

El cliente Docker envía todo el "contexto de compilación" al demonio Docker. Ese contexto de compilación (por defecto) es el directorio completo en el que se Dockerfileencuentra (entonces, el rpmsárbol completo ).

Puede configurar un .dockerignorearchivo para que Docker ignore algunos archivos. Es posible que desee experimentar con él.

Alternativamente, puede mover su rpmscarpeta un nivel de directorio por encima de su Dockerfile, y solo enlace simbólico test.rpmen el Dockerfiledirectorio de.


Como muchos usuarios señalaron en los comentarios, uno necesita agregar la .gitcarpeta a la.dockerignore que fue la causa de una diferencia de 150 MB -> 5 GB en mi caso.

Thomas Orozco
fuente
44
Desafortunadamente, parece que el enlace simbólico no es posible en este caso ya que el ADDcomando no sigue los enlaces sym durante una compilación. Ver: github.com/docker/docker/issues/1676
JimmidyJoo
55
salvavidas! Desarrolladores de Rails: asegúrese de agregar tmp loga .dockerignore+ otros personalizados
equivalente8
77
no olvide agregar la carpeta .git al archivo .dockerignore (suponiendo que esté usando git)
dsncode
8
Sí, la .gitcarpeta está incluida por defecto, esto definitivamente me sorprendió.
Paul Suart
1
¿Qué es exactamente el "contexto de construcción"? Traté de buscar estos archivos usando el comando Docker build RUN, pero no veo los archivos en mi carpeta Dockerfile dentro del sistema de archivos docker (durante el tiempo de compilación). ¿Alguien puede darme un ejemplo simple de cómo es útil el contexto de compilación?
Patrick
52

Actualización 2019

A partir de Docker v18.06, hay una opción para usar un nuevo generador de imágenes llamado Build Kit .

Está incluido con el Docker, no es necesario instalar nada. Es compatible con la Dockerfilesintaxis, no es necesario cambiar el Dockerfile.

Legacy Docker Build vs New Docker BuildKit

Aquí hay un ejemplo de cómo construir una imagen con un gran archivo sin usar en el directorio de compilación:

Docker Legacy Build:

$ 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

Nuevo 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

El único cambio es la DOCKER_BUILDKIT=1variable de entorno, la diferencia en el tiempo es enorme.

.dockerignore Expediente

Tenga en cuenta que el .dockerignorearchivo sigue siendo válido y útil. Algunos Dockerfilecomandos como COPY . .seguirán teniendo en cuenta las .dockerignorereglas. Pero los archivos secundarios en el directorio de compilación (no referenciados en el Dockerfile) ya no se copian como un "contexto de compilación" por parte del BuildKit.

Andriy Berestovskyy
fuente
1
Es importante tener en cuenta que DOCKER_BUILDKIT no es compatible actualmente con los contenedores de Windows. (Solo Linux, listado bajo limitaciones: docs.docker.com/develop/develop-images/build_enhancements )
Vaccano
18

Lo arreglé moviendo mi Dockerfile y docker-compose.yml a una subcarpeta y funcionó muy bien. Aparentemente, Docker envía la carpeta actual al demonio y mi carpeta tenía 9 conciertos.

Emad
fuente
44
Este método proporciona la ruta prohibida: fuera del error de contexto de compilación si se copia un archivo de un directorio principal, ¿alguna solución para esto?
Kitwradr
8

Si tiene un .dockerignorearchivo y el contexto de compilación sigue siendo grande, puede verificar lo que se envía al contexto de compilación de la ventana acoplable utilizando The Silver Searcher :

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

Tenga en cuenta que algunos **patrones pueden no funcionar correctamente.

Vea este número de Github para comentarios adicionales: https://github.com/moby/moby/issues/16056

Luís Bianchin
fuente
4

En mi caso, fue cuando -fejecuté con argumentos incorrectos , sin ruta al directorio donde se encontraba Dockerfile

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

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

FreeStyler
fuente
1

Si desea tener el control total de su contexto de compilación, también puede compilar el contenedor completamente sin ningún contexto y COPYdatos relevantes en el contenedor después.

docker build - < Dockerfile

Una desventaja de esto sería que con este enfoque solo puedes ADD cosas en el dockerfile que hacen referencia a una URL remota, y no archivos de su host local.

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

Christian.D
fuente
0

Tuve el mismo problema que FreeStyler. Sin embargo, estaba construyendo desde un directorio uno desde mi contexto. Entonces, los argumentos -f eran correctos, el contexto era incorrecto.

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

Construyendo desde el docker-dir lo siguiente estuvo bien

docker build -t br_base:0.1 . 

Construyendo desde el dock-dir, el contexto de construcción cambió. Por lo tanto, necesitaba cambiar el contexto en el comando. El contexto está dado por el '.' en el comando de arriba.

El nuevo comando del directorio del proyecto debe ser

docker build -t br_base:0.1 ./base

El contexto aquí está dado por el './base'

BravoRomeo23
fuente
0

si está creando una imagen y recibe un mensaje que envía el contexto de compilación al docker daemon, que está tardando en copiarse,

luego agregue el archivo .dockerignore . Debe incluir los archivos o el directorio que no es necesario copiar.

Shashikant Pandit
fuente
0

Para NodeJS Application, agregue un .dockerignorearchivo al directorio del proyecto raíz y dentro del .dockerignorearchivo agregue lo siguiente

node_modules
dist
Bernard Nongpoh
fuente