Entender el caché de capas de Docker
Qué cubre este artículo sobre Docker Layer-Caching
- Cómo funciona el caché de compilación de Docker.
- Qué causa la invalidación de capas.
- Cómo usar Cache-Mounts.
- Consejos prácticos para compilaciones más rápidas.
- Caché en CI/CD y en local.
Introducción: Entender el caché de capas de Docker
Cada línea en un Dockerfile genera una capa. Docker almacena estas capas en caché y las reutiliza cuando nada ha cambiado. Quien elige el orden correcto de los comandos puede reducir drásticamente los tiempos de compilación. Sin embargo, un único archivo modificado al principio del Dockerfile invalida todas las capas posteriores. Entender el caché de capas es por tanto fundamental para construir imágenes de Docker de manera eficiente.
Este artículo explica cómo funciona el caché y cómo aprovecharlo al máximo.
Términos clave
- Capa: Nivel de una imagen de Docker.
- Caché de compilación: Almacenamiento intermedio para capas.
- Invalidación de caché: Pérdida de validez de una capa.
- BuildKit: Constructor de Docker moderno con caché mejorado.
- Cache-Mount: Caché temporal dentro de una compilación.
- Pull-Through Cache: Almacenamiento intermedio para imágenes.
- Caché de Registry: Almacenamiento en caché en un Registry remoto.
- Snapshot: Estado intermedio de una capa.
Cómo funciona el caché
Cuando se compila una imagen, Docker verifica para cada instrucción si ya existe una capa idéntica. Si existe, reutiliza la capa del caché. Si no, construye una capa nueva e invalida todas las posteriores.
Una capa se considera sin cambios cuando:
- El comando es idéntico.
- Los archivos de entrada son idénticos.
- La capa anterior es idéntica.
Respetar el orden
Copiar primero los archivos que cambian con menos frecuencia:
# Bien: dependencias antes del código fuente
COPY package*.json ./
RUN npm ci
COPY . .
# Mal: cada cambio de código invalida npm ci
COPY . .
RUN npm ci
Invalidación de caché
Cualquier cambio en un archivo que precede a COPY invalida el caché. Esto es especialmente importante en compilaciones multietapa y con dependencias de compilación.
Ejemplo:
COPY package.json /app
RUN npm install
Si package.json cambia, npm install debe ejecutarse de nuevo.
BuildKit Cache-Mounts
BuildKit permite Cache-Mounts que persisten durante una compilación:
# syntax=docker/dockerfile:1.7
FROM python:3.11-slim
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
Esto preserva el caché de Pip entre compilaciones.
Caché de npm
# syntax=docker/dockerfile:1.7
FROM node:20-slim
RUN --mount=type=cache,target=/root/.npm \
npm ci
Caché de Maven
# syntax=docker/dockerfile:1.7
FROM maven:3.9-eclipse-temurin
RUN --mount=type=cache,target=/root/.m2 \
mvn package -DskipTests
Caché en CI/CD
En entornos de integración continua, el caché a menudo no es persistente. Las soluciones incluyen:
docker buildxconcache-fromycache-to.- Backends de caché externos como S3 o Registry.
- Capas de caché en Docker Registry.
docker buildx build \
--cache-from=type=registry,ref=user/image:cache \
--cache-to=type=registry,ref=user/image:cache,mode=max \
-t user/image:latest .
Verificar el caché local
docker system df
Limpiar caché:
docker builder prune
Estadísticas de caché
BuildKit muestra qué capas provienen del caché:
DOCKER_BUILDKIT=1 docker build --progress=plain .
La salida con CACHED indica capas reutilizadas.
Consejos para compilaciones rápidas
- Copiar primero los archivos que cambian raramente.
- Establecer
.dockerignore. - Agrupar comandos
RUN, pero solo cuando corresponda. - Usar Cache-Mounts.
- No ejecutar
RUN apt-get updatede forma aislada varias veces. - Almacenar el caché de CI externamente.
- Combinar compilaciones multietapa.
Errores comunes
- Caché inválido:
COPY . .demasiado pronto. - Demasiadas capas: Cada
RUNcrea su propia capa. - El caché crece demasiado: Nunca ejecutar
docker builder prune. - CI sin caché: Cada compilación comienza desde cero.
- Imágenes base antiguas: Sin almacenamiento en caché de las últimas actualizaciones de seguridad.
- Falta
.dockerignore: Cambios en archivos irrelevantes invalidan las capas.
Enlaces e información adicional
- BotServ.de Escribir Dockerfile
- BotServ.de Docker Compilaciones Multietapa
- BotServ.de Optimización de imagen Docker
- BotServ.de Comandos Docker
Preguntas frecuentes: Docker Layer-Caching
¿Cuánto tiempo persiste el caché? Localmente hasta su eliminación manual, en CI normalmente entre compilaciones.
¿Por qué se invalida mi caché? Porque han cambiado archivos, comandos o imágenes base.
¿Siempre debo usar BuildKit? Sí, ofrece mejores opciones de almacenamiento en caché.
¿Qué es un Cache-Mount? Un almacenamiento persistente durante la compilación, por ejemplo para cachés de paquetes.
¿Cómo verifico si las capas están en caché?
Con --progress=plain durante la compilación.
Fuentes y lecturas adicionales
- Docker Cache: https://docs.docker.com/build/cache/
- BuildKit: https://docs.docker.com/build/buildkit/
- Backends de caché: https://docs.docker.com/build/cache/backends/
Resumen: Entender el caché de capas de Docker
El caché de capas de Docker acelera las compilaciones considerablemente cuando el orden de las instrucciones es correcto y los archivos que cambian raramente se copian primero. BuildKit extiende el almacenamiento en caché con Cache-Mounts para gestores de paquetes y backends de caché externos. .dockerignore, compilaciones multietapa limpias y mantenimiento regular del caché son herramientas importantes para lograr compilaciones rápidas y reproducibles. Quien entiende el caché ahorra tiempo tanto localmente como en la tubería CI/CD.


