
Durante mucho tiempo, he creado una aplicación usando Docker con un contenedor intermedio, por ejemplo, crearía myapp:base
una que tiene todos los archivos principales copiados:
FROM ubuntu:17.10
ADD app /app
Ahora, el contenedor principal myapp:release
podría crearse simplemente con esto
FROM myapp:base
ADD app /app
Es posible que se modifiquen algunos archivos en el app
directorio y terminaría con una pequeña capa adicional.
Sin embargo, recientemente, esta final ADD
ha dado como resultado una capa mucho más grande y sospecho que está relacionada con una actualización de Docker (estoy usando la versión 18.02.0-ce de Docker, compilación fc4de44).
¿Ha cambiado algo en la forma en que Docker descubre qué es diferente? ¿Cómo puedo volver a una compilación eficiente que solo tiene una pequeña cantidad de archivos actualizados en una capa?
Pasos para reproducir:
# make a dummy dir with a 64kb file in it
mkdir -p files
truncate -s 64k files/64k.file
# base container has a copy of the files
cat << EOF > Dockerfile.base
FROM ubuntu:16.04
COPY files/ /root/
EOF
# derived container should just have any updates
cat << EOF > Dockerfile.derived
FROM q899941:base
COPY files/ /root/
EOF
# build them....
docker build --file Dockerfile.base -t q899941:base .
docker build --file Dockerfile.derived -t q899941:derived .
# now let's review the layers
docker history q899941:derived
obtengo este resultado
IMAGE CREATED CREATED BY SIZE
4e1eb5168d55 Less than a second ago /bin/sh -c #(nop) COPY dir:8e20ede288278c71e… 65.5kB
022626ac5cf0 Less than a second ago /bin/sh -c #(nop) COPY dir:8e20ede288278c71e… 65.5kB
0458a4468cbc 5 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 5 weeks ago /bin/sh -c mkdir -p /run/systemd && echo 'do… 7B
<missing> 5 weeks ago /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$… 2.76kB
<missing> 5 weeks ago /bin/sh -c rm -rf /var/lib/apt/lists/* 0B
<missing> 5 weeks ago /bin/sh -c set -xe && echo '#!/bin/sh' > /… 745B
<missing> 5 weeks ago /bin/sh -c #(nop) ADD file:a3344b835ea6fdc56… 112MB
La capa superior es de 64 kb aunque no se hayan modificado archivos.
Respuesta1
Parece que esto es unproblema conocido, ¡pero no uno que le importe a suficiente gente!
- ¿Hay alguna manera de agregar solo archivos modificados a una imagen de la ventana acoplable como una nueva capa, sin recurrir a la confirmación de la ventana acoplable?es una pregunta de StackOverflow que cubre el mismo tema.
- Parece que el comportamiento que esperaba funcionó con el controlador de almacenamiento superpuesto, pero después de algunas actualizaciones del sistema comencé a usar overlay2, que copiará todos los archivos en una capa y no solo los modificados.
- Si bien una solución sería volver a la superposición, parece bastante obsoleta en este momento.Aquí se detalla un método alternativo para crear capas 'diff'
Terminé haciendo una cosa simple mencionada en uno de loscomentariosen el informe de error:
#clean up any previous attempt...
docker rm -f uniquename 2> /dev/null
# now take your base container, mount the updated dir as /src
# then rsync from /src to the target dir - only updated files will
# actually be written, and we use --delete to ensure removed files are
# taken out...
docker run --name uniquename \
-v ~/repo/mycode:/src \
${REPO}/${IMAGE}:${BASE} \
rsync -ar --no-owner --no-group \
--exclude-from '/src/.dockerignore' --delete \
/src/ /app/
# we can commit that updated container with a tag
docker commit uniquename ${REPO}/${IMAGE}:${NEW_TAG}
Una cosa más: esta solución pareció eliminar el CMD
comando de inicio predeterminado que proporcionaba a mis contenedores. Entonces, después de agregar esta capa de diferencias, tuve otro Dockerfile para crear un contenedor a partir de la compilación 'diff' anterior con el CMD
agregado nuevamente.