Hice una imagen simple a través de Dockerfile desde Fedora (inicialmente 320 MB).
Se agregó Nano (este pequeño editor de 1 MB de tamaño), y el tamaño de la imagen ha aumentado a 530 MB. Agregué Git además de eso (30-ish MB), y luego mi tamaño de imagen se disparó a 830 MB.
¿No es una locura?
Intenté exportar e importar contenedores para eliminar el historial / imágenes intermedias. Este esfuerzo ahorró hasta 25 MB, ahora mi tamaño de imagen es de 804 MB. También he intentado ejecutar muchos comandos en uno RUN
, pero aún obtengo los mismos 830 MB iniciales.
Tengo mis dudas sobre si vale la pena usar Docker. Quiero decir, apenas instalé nada y estoy llegando a 1GB. Si tuviera que agregar algunas cosas serias como una base de datos, etc., podría quedarme sin espacio en disco.
¿Alguien sufre de un tamaño ridículo de imágenes? ¿Cómo lo afrontas?
¿A menos que mi Dockerfile sea horriblemente incorrecto?
FROM fedora:latest
MAINTAINER Me NotYou <[email protected]>
RUN yum -y install nano
RUN yum -y install git
Pero es difícil imaginar qué podría salir mal aquí.
yum clean all
Tiene algún efecto en el tamaño?docker images
cual en la última columna indica un considerable 830MB. Es posible que no sepa cuál es el tamaño real de mi imagen, ya que el comando docker images indica que este 830 MB es de tamaño virtual. Pero, de nuevo, ¿cuál es el tamaño real de la imagen?Respuestas:
Como dijo @rexposadas, las imágenes incluyen todas las capas y cada capa incluye todas las dependencias de lo que instaló. También es importante tener en cuenta que las imágenes base (como
fedora:latest
tienden a ser muy básicas) . Puede sorprenderse por la cantidad de dependencias que tiene su software instalado.Pude hacer que su instalación sea significativamente más pequeña al agregar
yum -y clean all
a cada línea:Es importante hacer eso para cada RUN, antes de que se confirme la capa, o de lo contrario las eliminaciones no eliminan los datos. Es decir, en un sistema de archivos de unión / copia en escritura, la limpieza al final no reduce realmente el uso del sistema de archivos porque los datos reales ya están comprometidos con las capas inferiores. Para evitar esto, debes limpiar cada capa.
fuente
docker images
). ¿Es posible eliminar / eliminar / destruir esas viejas capas? Para ser más específico: me gustaría eliminar por completo (basándome en su ejemplo) imágenes: 172743bd5d60, 3f2fed40e4b0, fd241224e9cf, 511136ea3c5a del historial, para que el tamaño de mi imagen virtual sea más o menos igual que el tamaño de la imagen final, aquí ~ 260MB .docker export
y luegodocker import
otra vez. Eso aplanaría las capas. No creo que reduzca el tamaño, pero podría estar equivocado.docker ps -s
muestra el tamaño real en HDD, que en mi caso fue-1B
. Eso suena razonable, menos 1 byte . He ganado algo de espacio en HDD ... parece legítimo.Las imágenes de Docker no son grandes, solo está creando imágenes grandes.
La
scratch
imagen es 0B y puede usarla para empaquetar su código si puede compilar su código en un binario estático. Por ejemplo, puede compilar su programa Go y empaquetarlo encimascratch
para crear una imagen totalmente utilizable que sea inferior a 5 MB.La clave es no usar las imágenes oficiales de Docker, son demasiado grandes. Scratch tampoco es tan práctico, así que recomiendo usar Alpine Linux como imagen base. Es ~ 5 MB, luego solo agregue lo que se requiere para su aplicación. Esta publicación sobre Microcontenedores le muestra cómo construir imágenes muy pequeñas basadas en Alpine.
ACTUALIZACIÓN: las imágenes oficiales de Docker se basan en alpino ahora, por lo que son buenas para usar ahora.
fuente
Aquí hay algunas cosas más que puede hacer :
RUN
comandos donde puedas. Ponga tanto como sea posible en unRUN
comando (usando&&
)Con estos Y las recomendaciones de @Andy y @michau pude cambiar el tamaño de mi imagen de nodejs de 1.062 GB a 542 MB.
Editar: Una cosa más importante: "Me tomó un tiempo comprender realmente que cada comando Dockerfile crea un nuevo contenedor con los deltas. [...] No importa si rm -rf los archivos en un comando posterior; continúan existiendo en algún contenedor de capa intermedia ". Así que ahora logrado poner
apt-get install
,wget
,npm install
(con dependencias GIT) yapt-get remove
en un soloRUN
comando, por lo que ahora mi imagen sólo tiene 438 MB.Editar 29/06/17
Con Docker v17.06, hay nuevas características para Dockerfiles: puede tener varias
FROM
declaraciones dentro de un Dockerfile y solo las últimas cosasFROM
estarán en su imagen final de Docker. Esto es útil para reducir el tamaño de la imagen, por ejemplo:Dará como resultado una imagen que solo tenga la imagen base de nodejs más el contenido de / var / my-project de los primeros pasos, ¡pero sin ruby, python, git, openssh y gcc!
fuente
Sí, esos tamaños son ridículos, y realmente no tengo idea de por qué tan poca gente lo nota.
Hice una imagen de Ubuntu que en realidad es mínima (a diferencia de otras llamadas imágenes "mínimas"). Se llama
textlab/ubuntu-essential
y tiene 60 MB.La imagen de arriba es de 82 MB después de instalar nano.
Git tiene muchos más requisitos previos, por lo que la imagen se agranda, aproximadamente 192 MB. Eso es aún menos que el tamaño inicial de la mayoría de las imágenes.
También puedes echar un vistazo a la secuencia de comandos que escribí para crear la imagen mínima de Ubuntu para Docker . Quizás pueda adaptarlo a Fedora, pero no estoy seguro de cuánto podrá desinstalar.
fuente
Lo siguiente me ayudó mucho:
Después de eliminar los paquetes no utilizados (por ejemplo, redis 1200 mb liberados) dentro de mi contenedor, hice lo siguiente:
Las capas se aplanan. El tamaño de la nueva imagen será menor porque he eliminado los paquetes del contenedor como se indicó anteriormente.
Me tomó mucho tiempo entender esto y es por eso que agregué mi comentario.
fuente
docker export <CONTAINER ID> | docker import - some-image-name:latest
Para la mejor práctica, debe ejecutar un solo comando RUN, porque cada instrucción RUN en el Dockerfile escribe una nueva capa en la imagen y cada capa requiere espacio adicional en el disco. Para mantener las capas de números al mínimo, cualquier manipulación de archivos como instalar, mover, extraer, eliminar, etc., idealmente debe realizarse bajo una sola instrucción RUN
fuente
Docker Squash es una buena solución para esto. puedes
$packagemanager clean
hacerlo en el último paso en lugar de en cada línea y luego simplemente ejecutar una docker squash para deshacerte de todas las capas.https://github.com/jwilder/docker-squash
fuente
Sí, el sistema de capas es bastante sorprendente. Si tiene una imagen base y la incrementa haciendo lo siguiente:
La imagen tiene exactamente el mismo tamaño. Eso significa esencialmente que debes lograr poner en tus pasos de RUN mucha magia de extracción, instalación y limpieza para hacer que las imágenes sean tan pequeñas como el software instalado.
Esto hace la vida mucho más difícil ...
A dockerBuild le faltan pasos de ejecución sin confirmación.
fuente