Guía Avanzada para Optimizar Builds de Docker y Acelerar el CI/CD

Última actualización: julio 2, 2026
Autor: Isaac
  • Implementación de compilaciones multi-etapa para separar el entorno de construcción del de ejecución.
  • Uso de imágenes base minimalistas como Alpine o Distroless para reducir la superficie de ataque y el peso.
  • Optimización del sistema de caché de Docker mediante el orden estratégico de capas y BuildKit.
  • Uso de herramientas de análisis como Dive para identificar espacio desperdiciado en las imágenes.

Optimización de Docker

Seguro que te ha pasado: lanzas un despliegue y te quedas mirando la pantalla mientras el pipeline de CI/CD parece haberse quedado congelado. Cuando trabajas en repositorios de gran tamaño, las imágenes de Docker pueden convertirse en auténticos monstruos que ralentizan todo el flujo de trabajo, inflan los costes de almacenamiento en la nube y hacen que la escalabilidad sea una pesadilla.

La buena noticia es que no tienes que resignarte a esos tiempos de espera infinitos. Con un par de ajustes inteligentes en el Dockerfile y el uso de herramientas adecuadas, puedes pasar de imágenes de gigabytes a unas de apenas unos pocos megabytes, logrando que tus despliegues vuelen y que la seguridad de tu infraestructura mejore drásticamente.

enfoque de github en infraestructura
Related article:
El enfoque de GitHub en infraestructura y automatización con IA

El arte de elegir la imagen base ideal

El cimiento de cualquier contenedor es su imagen base. Si eliges una distribución completa de un sistema operativo, estarás arrastrando cientos de paquetes que no necesitas. Para evitar esto, lo ideal es optar por variantes minimalistas. Alpine Linux es el rey en este aspecto, ya que apenas ocupa 5 MB, aunque hay que tener en cuenta que usa musl libc, lo que a veces puede dar algún quebradero de cabeza con la compatibilidad de ciertos binarios.

  Cómo Desactivar el Firewall de Windows 10 Usando CMD

Si necesitas algo más robusto pero sigues queriendo eficiencia, las versiones slim de Debian o Ubuntu son una opción equilibrada. Pero si quieres ir a niveles extremos de minimalismo, las imágenes distroless o scratch son la clave; estas eliminan incluso la shell y las herramientas básicas, dejando solo el binario de tu aplicación, lo que reduce la superficie de ataque y el peso al mínimo absoluto.

Dominando las capas y el sistema de caché

Docker funciona apilando capas, y cada instrucción como RUN, COPY o ADD crea una nueva. El truco para que el build sea rápido es maximizar los aciertos de caché. Para lograrlo, debes organizar tu Dockerfile de forma estratégica: coloca las instrucciones que nunca o rara vez cambian al principio y deja el código fuente, que es lo que más varía, para el final.

Un error muy común es crear capas innecesarias. En lugar de lanzar cinco comandos RUN distintos, lo mejor es encadenar instrucciones usando el operador &&. Por ejemplo, actualizar el gestor de paquetes, instalar la herramienta y limpiar los archivos temporales en una sola línea evita que la basura se quede grabada en una capa intermedia, logrando que la imagen final sea mucho más ligera.

habilidades de desarrollador
Related article:
Habilidades de desarrollador que te convierten en un profesional completo

Estrategias de Multi-stage Builds

Esta es probablemente la técnica más potente para optimizar el tamaño. La idea es sencilla: usar una imagen pesada y completa para compilar el código (etapa de builder) y luego copiar solo el artefacto final (el binario o el archivo .jar) a una imagen de ejecución mucho más pequeña.

  Cómo suspender Windows 10: Guía paso a paso

Imagina un proyecto de Node.js: en la primera etapa instalas todas las dependencias de desarrollo y ejecutas el build. En la segunda etapa, solo traes la carpeta dist y las dependencias de producción. De este modo, todas las herramientas de compilación y los cachés de npm desaparecen del artefacto final, reduciendo la imagen en un 60% o incluso un 80%.

BuildKit y el paralelismo avanzado

Si quieres llevar la velocidad al siguiente nivel, tienes que activar BuildKit configurando la variable DOCKER_BUILDKIT=1. Esta herramienta permite ejecutar etapas independientes en paralelo. Si tu monorepo tiene un frontend en React y un backend en Go, BuildKit puede compilar ambos simultáneamente, recortando el tiempo total de espera considerablemente.

Además, BuildKit introduce los montajes de caché. Mediante el uso de --mount=type=cache, puedes persistir los directorios de caché de gestores como apt, pip o npm entre diferentes ejecuciones de build. Esto evita que el contenedor tenga que descargar todo el árbol de dependencias desde cero cada vez que lanzas un pull request.

Análisis profundo con Dive y .dockerignore

A veces no sabemos exactamente qué está hinchando nuestra imagen. Aquí es donde entra Dive, una herramienta de código abierto que te permite explorar las capas de la imagen y ver exactamente qué archivos se añadieron o modificaron en cada paso. Es como hacer una autopsia de tu contenedor para identificar el espacio desperdiciado.

Para complementar esto, el archivo .dockerignore es fundamental. Si no lo usas, Docker enviará todo el contexto del directorio al demonio de build, incluyendo la carpeta .git, los logs o los node_modules locales. Excluir estos elementos no solo hace que el envío del contexto sea instantáneo, sino que evita que archivos innecesarios terminen dentro de la imagen por accidente.

  ¿Cómo se instala MySQL Installer?

Optimización de dependencias y limpieza de binarios

No basta con elegir una buena base; hay que ser meticulosos con lo que instalamos. Al usar gestores de paquetes, es recomendable usar la bandera --no-install-recommends para evitar que se instalen paquetes sugeridos que no son críticos. Asimismo, es vital ejecutar la limpieza de los listados de paquetes con rm -rf /var/lib/apt/lists/* en la misma capa donde se instalaron.

Para quienes trabajan con lenguajes compilados, el uso del comando strip puede ser un salvavidas. Al eliminar los símbolos de depuración de los binarios después de la compilación, se puede reducir el tamaño del ejecutable entre un 30% y un 60% sin afectar en nada al funcionamiento de la aplicación en producción, optimizando así la transferencia de datos en la red.

Tener un control total sobre el diseño de las capas, aprovechar el paralelismo de BuildKit y ser agresivos con la limpieza de archivos temporales permite que los equipos de desarrollo recuperen horas de productividad. Al reducir el peso de los contenedores y optimizar el uso de la caché, se consigue un flujo de CI/CD mucho más ágil, con costes de infraestructura menores y una velocidad de despliegue que realmente impulsa el ritmo de negocio.