Mira la lección en vídeo
Accede al vídeo completo de esta lección y a más contenido exclusivo con el Plan Plus.
Desbloquear Plan PlusCaché de capas BuildKit
El sistema de caché de capas de BuildKit es uno de los mecanismos más importantes para acelerar el proceso de construcción de imágenes Docker. Este sistema almacena automáticamente cada capa generada durante el build, permitiendo reutilizar resultados de instrucciones anteriores cuando las condiciones son idénticas.
Funcionamiento del caché de capas
BuildKit mantiene un índice de capas basado en el hash de cada instrucción del Dockerfile junto con su contexto. Cuando ejecutas un build, BuildKit compara cada instrucción con las capas existentes en su caché local para determinar si puede reutilizar una capa previa o necesita ejecutar la instrucción nuevamente.
FROM node:18-alpine
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
RUN npm run build
En este ejemplo, si solo modificas el código fuente pero no el package.json
, BuildKit reutilizará las capas correspondientes a FROM
, WORKDIR
, COPY package.json
y RUN npm install
, ejecutando únicamente las dos últimas instrucciones.
Invalidación secuencial de caché
La invalidación de caché sigue un principio fundamental: una vez que una instrucción invalida su caché, todas las instrucciones posteriores también se invalidan automáticamente. Esta invalidación secuencial garantiza la consistencia pero requiere una estrategia cuidadosa en el orden de las instrucciones.
FROM nginx:alpine
# Esta capa se cachea si nginx:alpine no cambia
RUN apk add --no-cache curl
# Si config.conf cambia, esta capa se invalida
COPY config.conf /etc/nginx/
# TODAS las capas posteriores se invalidan automáticamente
COPY src/ /usr/share/nginx/html/
RUN chmod -R 644 /usr/share/nginx/html/
Optimización del orden de instrucciones
Para maximizar la eficiencia del caché, coloca las instrucciones que cambian con menos frecuencia al principio del Dockerfile:
Ejemplo mal optimizado:
FROM python:3.11-slim
# Esto cambia frecuentemente e invalida todo el caché
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
Ejemplo bien optimizado:
FROM python:3.11-slim
WORKDIR /app
# Primero copiamos solo requirements.txt
COPY requirements.txt .
# Esta capa solo se invalida si requirements.txt cambia
RUN pip install -r requirements.txt
# El código fuente se copia al final
COPY . .
Caché y contexto de build
BuildKit considera tanto el contenido como los metadatos de los archivos para generar el hash de cada capa. Esto incluye:
- Contenido de archivos copiados
- Permisos y timestamps (cuando son relevantes)
- Variables de entorno utilizadas en la instrucción
- Argumentos de build (ARG) activos
FROM alpine:latest
# El caché se invalida si cambia el contenido de script.sh
COPY script.sh /usr/local/bin/
# También se invalida si cambian los permisos
RUN chmod +x /usr/local/bin/script.sh
Límites del caché local
El caché local de BuildKit tiene limitaciones importantes en entornos de desarrollo y CI/CD:
- Solo persiste mientras el daemon Docker esté activo
- No se comparte entre diferentes máquinas
- Se puede llenar y requerir limpieza manual con
docker builder prune
Para superar estas limitaciones, BuildKit ofrece opciones de caché remoto que permiten compartir capas entre builds y equipos, tema que abordaremos en la siguiente sección sobre cache-from
y cache-to
.
Inspección del caché
Puedes verificar el uso del caché observando la salida del build:
docker build -t mi-app .
Las líneas que muestran CACHED
indican que BuildKit reutilizó una capa existente:
=> CACHED [2/5] WORKDIR /app 0.0s
=> CACHED [3/5] COPY package.json . 0.0s
=> [4/5] COPY . . 0.1s
cache-from y cache-to
Guarda tu progreso
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
Los flags --cache-from y --cache-to de BuildKit permiten utilizar fuentes de caché externas y compartir capas entre diferentes builds, superando las limitaciones del caché local. Estas opciones son fundamentales para optimizar builds en entornos de desarrollo distribuido y pipelines de CI/CD.
Sintaxis básica de cache-from y cache-to
El flag --cache-from especifica las fuentes desde las que BuildKit puede importar capas cacheadas, mientras que --cache-to define dónde exportar el caché para futuros builds:
docker buildx build \
--cache-from type=registry,ref=myregistry.com/myapp:cache \
--cache-to type=registry,ref=myregistry.com/myapp:cache,mode=max \
-t myregistry.com/myapp:latest .
Estas opciones funcionan exclusivamente con BuildKit, que está habilitado por defecto en Docker Engine 28. Para builds tradicionales sin BuildKit, estos flags no tienen efecto.
Tipo de caché: local
El tipo local permite almacenar el caché en el sistema de archivos local, útil para desarrollo y builds frecuentes en la misma máquina:
# Exportar caché a directorio local
docker buildx build \
--cache-to type=local,dest=/tmp/cache \
-t nginx-custom .
# Importar desde caché local
docker buildx build \
--cache-from type=local,src=/tmp/cache \
-t nginx-custom .
Este enfoque es especialmente efectivo para monorepos donde múltiples servicios comparten dependencias base:
# Build del servicio frontend
docker buildx build \
--cache-from type=local,src=./cache/shared \
--cache-to type=local,dest=./cache/frontend \
-f frontend/Dockerfile .
# Build del servicio backend reutilizando caché compartido
docker buildx build \
--cache-from type=local,src=./cache/shared \
--cache-from type=local,src=./cache/frontend \
--cache-to type=local,dest=./cache/backend \
-f backend/Dockerfile .
Tipo de caché: registry
El tipo registry almacena el caché como una imagen en un registro Docker, permitiendo compartir capas entre diferentes máquinas y equipos:
# Primer build: exporta caché al registry
docker buildx build \
--cache-to type=registry,ref=docker.io/usuario/postgres-custom:cache \
-t usuario/postgres-custom:latest \
-f postgres/Dockerfile .
# Builds posteriores: importa caché desde registry
docker buildx build \
--cache-from type=registry,ref=docker.io/usuario/postgres-custom:cache \
--cache-to type=registry,ref=docker.io/usuario/postgres-custom:cache \
-t usuario/postgres-custom:v2.0 \
-f postgres/Dockerfile .
El parámetro mode=max incluye todas las capas intermedias en el caché, no solo las del resultado final:
docker buildx build \
--cache-to type=registry,ref=myregistry.com/mysql-custom:cache,mode=max \
-t myregistry.com/mysql-custom:latest .
Tipo de caché: inline
El tipo inline almacena los metadatos de caché directamente dentro de la imagen resultante, simplificando la gestión:
# Build con caché inline embebido
docker buildx build \
--cache-to type=inline \
-t usuario/nginx-app:latest .
# Reutilizar caché desde la propia imagen
docker buildx build \
--cache-from type=registry,ref=usuario/nginx-app:latest \
-t usuario/nginx-app:v2.0 .
Esta opción es conveniente pero aumenta el tamaño de la imagen final, ya que incluye metadatos adicionales.
Múltiples fuentes de caché
BuildKit permite combinar múltiples fuentes de caché para maximizar la reutilización de capas:
docker buildx build \
--cache-from type=registry,ref=base-images/node:18-cache \
--cache-from type=registry,ref=myapp:cache \
--cache-from type=local,src=./local-cache \
--cache-to type=registry,ref=myapp:cache,mode=max \
-t myapp:latest .
BuildKit evalúa las fuentes en orden y utiliza la primera coincidencia disponible para cada capa.
Estrategias para monorepos
En monorepos con múltiples servicios, una estrategia efectiva es mantener cachés específicos por servicio y uno compartido para dependencias comunes:
# Caché base compartido para todas las aplicaciones Node.js
docker buildx build \
--cache-from type=registry,ref=monorepo/node-base:cache \
--cache-to type=registry,ref=monorepo/node-base:cache \
-f docker/base-node.Dockerfile .
# Service específico utilizando caché base
docker buildx build \
--cache-from type=registry,ref=monorepo/node-base:cache \
--cache-from type=registry,ref=monorepo/api-service:cache \
--cache-to type=registry,ref=monorepo/api-service:cache,mode=max \
-f services/api/Dockerfile .
Consideraciones de rendimiento
El uso de --cache-from con registries remotos introduce latencia de red durante la fase de importación. Para optimizar el rendimiento:
- 1. Combina local y registry: Utiliza caché local como primera opción y registry como respaldo
docker buildx build \
--cache-from type=local,src=./cache \
--cache-from type=registry,ref=myapp:cache \
--cache-to type=local,dest=./cache \
--cache-to type=registry,ref=myapp:cache \
-t myapp:latest .
- 2. Usa mode=min para cachés registry: Reduce el tamaño de transferencia incluyendo solo las capas esenciales
docker buildx build \
--cache-to type=registry,ref=myapp:cache,mode=min \
-t myapp:latest .
Verificación del caché remoto
Para confirmar que BuildKit está utilizando correctamente las fuentes de caché externas, observa la salida del build buscando líneas como:
=> importing cache manifest from myregistry.com/myapp:cache
=> CACHED [stage-0 2/5] WORKDIR /app
La presencia de importing cache manifest
confirma que BuildKit ha encontrado y está utilizando la fuente de caché especificada.
Aprendizajes de esta lección de Docker
- Comprender el funcionamiento del caché de capas en BuildKit y su impacto en la construcción de imágenes Docker.
- Aprender cómo la invalidación secuencial afecta la reutilización del caché y cómo optimizar el orden de instrucciones en Dockerfile.
- Conocer las limitaciones del caché local y las ventajas de usar caché remoto con cache-from y cache-to.
- Saber configurar diferentes tipos de caché (local, registry, inline) para mejorar la eficiencia en entornos distribuidos y CI/CD.
- Aplicar estrategias de caché en monorepos y entender consideraciones de rendimiento al usar caché remoto.
Completa este curso de Docker y certifícate
Únete a nuestra plataforma de cursos de programación y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs