¿Cómo puedo evitar que una instrucción de Dockerfile se almacene en caché?


En mi Dockerfile uso curl o ADD para descargar la última versión de un archivo como:

FROM debian:jessie
...
RUN apt-get install -y curl
...
RUN curl -sL http://example.com/latest/archive.tar.gz --output archive.tar.gz
...
ADD http://example.com/latest/archive2.tar.gz
...

La instrucción RUN que usa curl o ADD crea su propia capa de imagen. Que se utilizará como caché para futuras ejecuciones de docker build.

Pregunta: ¿Cómo puedo desactivar el almacenamiento en caché de esas instrucciones?

Sería genial tener algo como invalidación de caché trabajando allí. Por ejemplo, usando HTTP ETags o consultando el último modificado campo de cabecera. Eso daría la posibilidad de hacer una comprobación rápida basada en las cabeceras HTTP para decidir si una capa en caché podría ser utilizada o no.

Sé que algunos trucos sucios podrían ayudar, por ejemplo, ejecutar un script de shell de descarga en la instrucción RUN en su lugar. Su nombre de archivo será cambiado antes de que el docker build sea activado por nuestro sistema de compilación. Y podría hacer las comprobaciones HTTP dentro de ese script. Pero luego necesito almacenar el último ETag usado o el último modificado a un archivo en algún lugar. Me pregunto si hay alguna funcionalidad de Docker más limpia y nativa que pueda usar aquí.

Author: h3nrik, 2015-08-03

3 answers

Se puede especificar un argumento en tiempo de compilación para romper por la fuerza la caché a partir de ese paso en adelante. Por ejemplo, en su Dockerfile, ponga

ARG CACHE_DATE=not_a_date

Y luego dar a este argumento un nuevo valor en cada nueva construcción. Lo mejor, por supuesto, es la marca de tiempo.

docker build --build-arg CACHE_DATE=$(date +%Y-%m-%d:%H:%M:%S) ...

Asegúrese de que el valor sea una cadena sin espacios, de lo contrario docker client lo tomará falsamente como múltiples argumentos.

Ver una discusión detallada sobre Número 22832.

 20
Author: Ruifeng Ma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-18 07:21:11

Docker build no no-cache invalidaría la caché para todos los comandos.

Dockerfile ADD command solía tener la caché invalidada. Aunque se ha mejorado en la versión docker reciente:

Docker se supone que debe checksum cualquier archivo agregado a través de ADDand y luego decidir si debe usar la caché o no.

Así que si el archivo añadido ha cambiado, la caché debe ser invalidada para el ADD comando.


El número 1326 menciona otros consejos:

Esto funcionó.

RUN yum -y install firefox #redo

Así que parece que Docker volverá a ejecutar el paso (y todos los pasos debajo de él) si la cadena que estoy pasando a RUN cambia de todos modos- incluso es solo un comentario.

La caché de docker solo se usa, y solo si ninguno de sus ancestros ha cambiado (este comportamiento tiene sentido, ya que el siguiente comando agregará cambios a la capa anterior).

La caché se usa si no hay ningún carácter que haya cambiado (por lo que incluso un espacio es suficiente para invalidar una caché).

 23
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-11 07:30:43

Agregar && exit 0 después de que un comando invalide la caché desde allí.

Ejemplo:

RUN apt-get install -y unzip && exit 0

 -3
Author: rolele,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-29 06:34:08