Deshabilitar la caché para comandos RUN específicos

98

Tengo algunos RUNcomandos en mi Dockerfile con los que me gustaría ejecutar -no-cachecada vez que construyo una imagen de Docker.

Entiendo docker build --no-cacheque deshabilitará el almacenamiento en caché para todo el Dockerfile.

¿Es posible deshabilitar la caché para un comando RUN específico?

Vingtoft
fuente
1
Una vez que deshabilita la caché para un solo comando, si el resultado no coincide con la ejecución anterior en caché, deberá reconstruir todos los pasos restantes. ¿Es ese su objetivo, o espera reconstruir solo una capa y de alguna manera inyectarla en el lugar donde se almacenaron los datos en caché anteriores?
BMitch
2
Esperaba reconstruir capas específicas, por ejemplo, un comando "git pull". En este momento, el comando "git pull" se almacenará en caché, aunque el repositorio esté actualizado.
Vingtoft
2
Es bastante fácil forzar un tirón pasando un argumento no utilizado. Pero el resultado de la reconstrucción de esa entrada almacenada en caché es que todas las capas siguientes necesitarán una reconstrucción. Vea mi respuesta aquí para ver un ejemplo.
BMitch
Si busca invalidar el caché cuando un control remoto de git ha cambiado, eche un vistazo a: Cómo evitar el clon de git de almacenamiento en caché de Dockerfile . Todo el crédito a @anq por la respuesta vinculada.
hpgmiskin

Respuestas:

79

Siempre hay una opción para insertar algún comando sin sentido y barato de ejecutar antes de la región para la que desea deshabilitar el caché.

Como se propone en el comentario de este problema , se puede agregar un bloque de argumento de compilación (el nombre puede ser arbitrario):

ARG CACHEBUST=1 

antes de dicha región, y modifique su valor en cada ejecución agregando --build-arg CACHEBUST=$(date +%s)comodocker build argumento (el valor también puede ser arbitrario, aquí es la fecha y hora actual, para garantizar su singularidad entre las ejecuciones).

Esto, por supuesto, también desactivará la caché para todos los bloques siguientes, ya que la suma hash de la imagen intermedia será diferente, lo que hace que la desactivación de la caché verdaderamente selectiva sea un problema no trivial, teniendo en cuenta cómo funciona actualmente Docker.

Vladislav
fuente
1
Parece que ya no funciona, acabo de entrar ---> Using cacheen mi línea `` ARG CACHEBUST = 1` ... (y sí, lo hice --build-arg CACHEBUST=$(date +%s)en mi comando docker)
Pylinux
Tampoco me funciona a mí, tal vez dependa de la plataforma. Hubiera esperado que cualquier cambio de ARG invalidara el caché.
Oliver
6
Debe agregar, RUN echo "$CACHEBUST"ya que solo usar ARGno invalidará el caché
Sidharth V
Esta respuesta resolvió mi problema aquí: stackoverflow.com/questions/63709147/…
shapiro yaacov
25

Utilizar

ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache

antes de la línea RUN que desea ejecutar siempre. Esto funciona porque ADD siempre buscará el archivo / URL y la URL anterior genera datos aleatorios en cada solicitud, Docker luego compara el resultado para ver si puede usar el caché.

También probé esto y funciona bien ya que no requiere ningún argumento adicional de línea de comando de Docker y también funciona desde un archivo Docker-compose.yaml :)

steve
fuente
2
¿Qué pasará si random.org decide cambiar ese punto final? ¿Cómo controlarías ese comportamiento?
Andres Leon Rangel
@AndresLeonRangel Es cierto que esta no es una función de Docker, sino una especie de pirateo que usa la sintaxis de Docker y un servicio web bien conocido que ha existido durante más de 20 años, sin embargo, tiene razón al decir que pueden desaprobar ese punto final, de hecho, están mirando sus documentos ahora. Ni siquiera puedo encontrar el punto final "randbyte" y tienen una nueva API actualmente en versión beta. Puede 1) continuar usando este punto final hasta que falle, 2) usar su nuevo punto final (hasta que falle) o 3) escribir su propio punto final aleatorio, en cuyo caso usted tiene el control total :)
steve
2
Esto falló algunas veces ... ¡cuando el sitio está caído! Creo que no es la solución perfecta para esto. ADD falló: no se pudo GET random.org/cgi-bin/randbyte?nbytes=10&format=h con estado 503 Servicio no disponible: <! DOCTYPE HTML>
Kathi
1
random.org ha agregado protección DDOS que rompe esta solución ahora
Brad Root
No funciona y una dirección dada devuelve 503. Si no desea bloquear sus tuberías, no use esta solución
OlegI
9

No directamente, pero puede dividir su Dockerfile en varias partes, crear una imagen, luego DESDE esta imagen al comienzo del siguiente Dockerfile y crear la imagen con o sin almacenamiento en caché.

usuario2915097
fuente
1
¿Permitirá esto actualizar las capas comprometidas en la imagen base de la ventana acoplable?
user_mda
7

A partir de febrero de 2016 no es posible.

La función ha sido solicitada en GitHub.

Vingtoft
fuente
3

la característica agregada hace una semana.

ARG FOO=bar

FROM something
RUN echo "this won't be affected if the value of FOO changes"
ARG FOO
RUN echo "this step will be executed again if the value of FOO changes"

FROM something-else
RUN echo "this won't be affected because this stage doesn't use the FOO build-arg"

https://github.com/moby/moby/issues/1996#issuecomment-550020843

Tha Sami
fuente
0

Creo que esta es una ligera mejora en la respuesta de @ steve, arriba:

RUN git clone https://sdk.ghwl;erjnv;wekrv;[email protected]/your_name/your_repository.git

WORKDIR your_repository

# Calls for a random number to break the cahing of the git clone
# (/programming/35134713/disable-cache-for-specific-run-commands/58801213#58801213)
ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache
RUN git pull

Esto usa la caché de Docker del clon de git, pero luego ejecuta una actualización sin caché del repositorio.

Se parece a trabajar, y es más rápido - pero muchas gracias a @steve para proporcionar los principios subyacentes.

Mike Sadler
fuente
-2

Otro truco rápido es escribir algunos bytes aleatorios antes de su comando

RUN head -c 5 /dev/random > random_bytes && <run your command>

escribe 5 bytes aleatorios que forzarán una falta de caché

marca
fuente
10
El resultado de escribir esos bytes aleatorios también se almacena en caché, por lo que si ningún archivo ha cambiado antes de ese comando, no volverá a ejecutarlo. Esto no resuelve nada.
Icy Defiance