Mi Dockerfile es algo como
FROM my/base
ADD . /srv
RUN pip install -r requirements.txt
RUN python setup.py install
ENTRYPOINT ["run_server"]
Cada vez que construyo una nueva imagen, las dependencias deben reinstalarse, lo que podría ser muy lento en mi región.
Una forma en la que pienso en los cache
paquetes que se han instalado es anular la my/base
imagen con imágenes más nuevas como esta:
docker build -t new_image_1 .
docker tag new_image_1 my/base
Entonces, la próxima vez que construya con este Dockerfile, mi / base ya tiene algunos paquetes instalados.
Pero esta solución tiene dos problemas:
- No siempre es posible anular una imagen base
- La imagen base crece cada vez más a medida que se superponen imágenes más nuevas.
Entonces, ¿qué mejor solución podría usar para resolver este problema?
EDITAR##:
Alguna información sobre la ventana acoplable en mi máquina:
☁ test docker version
Client version: 1.1.2
Client API version: 1.13
Go version (client): go1.2.1
Git commit (client): d84a070
Server version: 1.1.2
Server API version: 1.13
Go version (server): go1.2.1
Git commit (server): d84a070
☁ test docker info
Containers: 0
Images: 56
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Dirs: 56
Execution Driver: native-0.2
Kernel Version: 3.13.0-29-generic
WARNING: No swap limit support
my/base
Respuestas:
Intente construir un Dockerfile que se parezca a esto:
Docker usará la caché durante la instalación de pip siempre que no realice ningún cambio en el
requirements.txt
, independientemente de si.
se cambiaron o no otros archivos de código en . He aquí un ejemplo.Aquí tienes un
Hello, World!
programa simple :La salida de la compilación de Docker:
Modifiquemos
run.py
:Intente construir de nuevo, a continuación se muestra el resultado:
Como puede ver arriba, esta vez la ventana acoplable usa caché durante la compilación. Ahora, actualice
requirements.txt
:A continuación se muestra el resultado de la compilación de Docker:
Observe cómo Docker no usó el caché durante la instalación de pip. Si no funciona, verifique su versión de Docker.
fuente
ADD
instrucción, la caché se invalida.ADD ./requirements.txt /srv/requirements.txt
activado), entonces la ventana acoplable debe usar la caché. Consulte agregar sección en el documento Dockerfile.ADD requirements.txt /srv
antes de ejecutar pip (RUN pip install -r requirements.txt
) y agrega todos los demás archivos después de ejecutar pip. Por lo tanto, deben estar en el siguiente orden: (1)ADD requirements.txt /srv
; (2)RUN pip install -r requirements.txt
; ( 3)ADD . /srv
Para minimizar la actividad de la red, puede apuntar
pip
a un directorio de caché en su máquina host.Ejecute su contenedor de la ventana acoplable con el enlace del directorio de caché pip de su host montado en el directorio de caché pip de su contenedor.
docker run
El comando debería verse así:Luego, en su Dockerfile, instale sus requisitos como parte de la
ENTRYPOINT
declaración (oCMD
declaración) en lugar de como unRUN
comando. Esto es importante, porque (como se señaló en los comentarios) el montaje no está disponible durante la construcción de la imagen (cuandoRUN
se ejecutan las declaraciones). El archivo Docker debería verse así:fuente
Entiendo que esta pregunta ya tiene algunas respuestas populares. Pero hay una forma más nueva de almacenar archivos en caché para los administradores de paquetes. Creo que podría ser una buena respuesta en el futuro cuando BuildKit se vuelva más estándar.
A partir de Docker 18.09, existe soporte experimental para BuildKit . BuildKit agrega soporte para algunas características nuevas en Dockerfile, incluido el soporte experimental para montar volúmenes externos en
RUN
pasos. Esto nos permite crear cachés para cosas como$HOME/.cache/pip/
.Usaremos el siguiente
requirements.txt
archivo como ejemplo:Un ejemplo típico de Python
Dockerfile
podría verse así:Con BuildKit habilitado usando la
DOCKER_BUILDKIT
variable de entorno, podemos construir elpip
paso sin caché en aproximadamente 65 segundos:Ahora, agreguemos el encabezado experimental y modifiquemos el
RUN
paso para almacenar en caché los paquetes de Python:Adelante, haz otra compilación ahora. Debería llevar la misma cantidad de tiempo. Pero esta vez está almacenando en caché los paquetes de Python en nuestro nuevo montaje de caché:
Aproximadamente 60 segundos. Similar a nuestra primera construcción.
Realice un pequeño cambio en
requirements.txt
(como agregar una nueva línea entre dos paquetes) para forzar una invalidación de caché y ejecutar nuevamente:¡Solo unos 16 segundos!
Estamos obteniendo esta aceleración porque ya no estamos descargando todos los paquetes de Python. Fueron almacenados en caché por el administrador de paquetes (
pip
en este caso) y almacenados en un montaje de volumen de caché. El montaje de volumen se proporciona al paso de ejecución para quepip
pueda reutilizar nuestros paquetes ya descargados. Esto sucede fuera de cualquier almacenamiento en caché de la capa de Docker .Las ganancias deberían ser mucho mejores a mayor tamaño
requirements.txt
.Notas:
Las cosas de BuildKit no funcionan bajo Docker Compose u otras herramientas que usan directamente la API de Docker en este momento.Ahora hay soporte para esto en Docker Compose a partir de la versión 1.25.0. Consulte ¿Cómo se habilita BuildKit con docker-compose?docker system prune -a
.Con suerte, estas características se convertirán en Docker para compilar y BuildKit se convertirá en el predeterminado. Si / cuando eso suceda, intentaré actualizar esta respuesta.
fuente
Dockerfile
o la versión de Docker es demasiado antigua. Crearía una nueva pregunta con toda su información de depuración.Descubrí que una mejor manera es simplemente agregar el directorio de paquetes de sitio de Python como un volumen.
De esta manera, puedo instalar nuevas bibliotecas sin tener que hacer una reconstrucción completa.
EDITAR : Ignore esta respuesta, la respuesta de jkukul anterior funcionó para mí. Mi intención era almacenar en caché la carpeta de paquetes del sitio . Eso habría parecido algo más parecido a:
Sin embargo, almacenar en caché la carpeta de descarga es mucho más limpio. Eso también almacena en caché las ruedas, por lo que realiza correctamente la tarea.
fuente