Skip to content
BotServBotServ
DockerCacheLayerBuildBuildKit

Entender Docker Layer-Caching

Usa correctamente el caché de Docker Build. Orden, invalidación, Cache-Mounts y builds acelerados.

S

schutzgeist

3 min read
Entender Docker Layer-Caching

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 buildx con cache-from y cache-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 update de forma aislada varias veces.
  • Almacenar el caché de CI externamente.
  • Combinar compilaciones multietapa.

Errores comunes

  • Caché inválido: COPY . . demasiado pronto.
  • Demasiadas capas: Cada RUN crea 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

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

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.

Volver al blog
Share:

Entradas relacionadas