Introducción
En el mundo del desarrollo y despliegue de software, los contenedores se han convertido en una herramienta esencial para garantizar que las aplicaciones funcionen de manera consistente en distintos entornos. Sin embargo, construir imágenes de contenedores optimizadas, tanto en tamaño como en eficiencia, puede ser un desafío, especialmente cuando se trabaja con entornos complejos que requieren distintas fases de construcción, como la compilación y la ejecución.
En este artículo, exploraremos en profundidad la técnica de Multi-Stage Build para trabajar con contenedores Docker. Esta metodología permite optimizar los procesos de construcción, reduciendo el tamaño final de las imágenes y mejorando la portabilidad y mantenimiento. A través de explicaciones detalladas, ejemplos prácticos y consejos expertos, este contenido pretende servir de guía técnica completa para desarrolladores, DevOps y arquitectos de software.
¿Qué es una Multi-Stage Build?
Una Multi-Stage Build es una característica avanzada de Docker que permite utilizar múltiples etapas (stages) en un único Dockerfile. Cada etapa puede comenzar a partir de una imagen base diferente, específica para la función que debe realizar (como compilación, pruebas, empaquetado, etc.).
Lo fundamental es que solo el resultado final de la última etapa se empaqueta en la imagen definitiva. El resto de etapas funcionan como etapas intermedias que ayudan a crear la imagen optimizada, pero no se incluyen en ella.
Ventajas principales de Multi-Stage Build
- Reducción del tamaño final de la imagen: Se eliminan herramientas y dependencias de compilación innecesarias en la imagen final.
- Seguridad: Al excluir recursos no necesarios en producción, se minimizan las vulnerabilidades.
- Mantenimiento simplificado: Un solo Dockerfile gestiona todo el proceso de construcción, disminuyendo errores y la complejidad.
- Portabilidad: La imagen final es independiente del entorno local del desarrollador.
El problema con las builds tradicionales
En construcciones tradicionales, los procesos de compilación y ejecución suelen estar mezclados, lo que conlleva a problemas como imágenes voluminosas y dependencias innecesarias en producción. Por ejemplo, cuando se usa una imagen base de SDK con todas las herramientas de desarrollo para compilar, la imagen resultante incluye todo ese peso extra.
En el ejemplo típico con .NET, la imagen creada que incluye el SDK puede pesar cientos de megabytes, mucho más de lo necesario para ejecutar el binario.
Limitaciones con imágenes basadas únicamente en SDK
- Imágenes excesivamente grandes (ejemplo: 833 MB para un “Hello World”).
- Dependencia de herramientas de compilación en producción.
- Tiempo de despliegue y transferencia mayor.
- Dificultades para garantizar consistencia y seguridad en entornos productivos.
Fundamentos de un Dockerfile Multistage
Un Dockerfile tradicional inicia con una única FROM
, que define la imagen base. En cambio, un Dockerfile para multi-stage utiliza múltiples instrucciones FROM
, cada una creando un “stage” independiente.
Cada stage puede hacer uso de distintos entornos y herramientas. El contenido necesario se transfiere entre stages usando la instrucción COPY --from=<stage>
, haciendo posible, por ejemplo, compilar en un stage y copiar solo los binarios al siguiente.
Estructura típica de un Dockerfile multistage
FROM imagen_sdk AS build # Instrucciones para compilar la aplicación FROM imagen_runtime AS final # Copiar solo el binario compilado desde el stage 'build' COPY --from=build /ruta/binario /ruta/app # Definir comando de arranque CMD ["./app/binario"]
Ejemplo práctico: Construir una imagen .NET usando Multi-Stage Build
Supongamos un proyecto .NET cuyo código fuente está en el directorio /code
. El objetivo es compilar el código usando la imagen con SDK y luego generar una imagen final liviana que solo contenga el runtime y el ejecutable.

Primer stage: compilación con SDK
Se inicia con la imagen mcr.microsoft.com/dotnet/sdk:8.0
(versión ejemplo), se copia el código fuente, se restaura y compila el proyecto.
Segundo stage: imagen final con runtime
Se utiliza la imagen mcr.microsoft.com/dotnet/runtime:8.0
, que no incluye el SDK. Aquí se copian los archivos compilados desde el stage build
y se establece el comando por defecto para ejecutar el binario.
Dockerfile completo
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /code COPY *.csproj ./ RUN dotnet restore COPY . ./ RUN dotnet publish -c Release -o /app FROM mcr.microsoft.com/dotnet/runtime:8.0 AS final WORKDIR /app COPY --from=build /app ./ ENTRYPOINT ["dotnet", "MiAplicacion.dll"]
Explicación detallada del proceso paso a paso
- Seleccionar imagen base del SDK: Incluye todas las herramientas de compilación y desarrollo.
- Setear directorio de trabajo: Para focalizar las operaciones dentro de una carpeta específica del contenedor.
- Copiar archivos de proyecto: Primero los archivos necesarios para restaurar dependencias y luego el resto del código.
- Restaurar dependencias: Descarga paquetes necesarios para la compilación.
- Compilar y publicar: Generar los binarios publicados optimizados para producción.
- Crear etapa final con runtime: Imagen más ligera que solo contiene el entorno de ejecución.
- Copiar binarios del stage build: Solo trasladar el resultado necesario para ejecución.
- Definir comando de arranque: Ejecutar la aplicación cuando el contenedor se inicie.
Buenas prácticas en Multi-Stage Build
- Nombrar stages: Utilizar aliases claros para cada stage con la sintaxis
AS nombre
, facilita la lectura y referencia posterior. - Ignorar archivos innecesarios: Usar
.dockerignore
para excluir carpetas comobin
,obj
o archivos temporales que no deben incluirse en la imagen. - Minimizar capas: Combinar instrucciones RUN, COPY y otros comandos para optimizar el número de capas de la imagen.
- Aprovechar caching: Ordenar instrucciones en Dockerfile para aprovechar mejor el cache y acelerar builds subsecuentes.
- Verificar versiones: Utilizar versiones fijas y actualizadas de las imágenes base para garantizar estabilidad y seguridad.
Comparativa entre una Build tradicional y una Multi-Stage Build
Característica | Build Tradicional (Una sola etapa) | Multi-Stage Build |
---|---|---|
Tamaño de imagen final | Grande (incluye SDK y herramientas de desarrollo) | Mucho más pequeño (solo runtime y binarios) |
Complejidad Dockerfile | Simplificado, una sola FROM | Más elaborada, varias etapas con múltiples FROM |
Tiempo de compilación | Puede ser largo por capas pesadas | Más eficiente gracias al caching y capas optimizadas |
Seguridad | Menor seguridad al incluir herramientas innecesarias | Mejor seguridad con menos superficie de ataque |
Mantenimiento | Menos modular, mayor probabilidad de errores | Modular, facilita depuración y actualización |
Errores comunes al trabajar con Multi-Stage Build y cómo evitarlos
- No nombrar las etapas (stages): Esto dificulta la gestión y referencia para copiar archivos entre ellas.
- Copiar rutas erróneas: Verificar que las rutas al copiar contenido entre stages son correctas y existen.
- Olvidar ignorar archivos con .dockerignore: Puede causar que archivos grandes no deseados aumenten innecesariamente la imagen.
- Confundir las instrucciones CMD y ENTRYPOINT: Elegir adecuadamente para definir el comportamiento del contenedor.
- Usar imágenes base inadecuadas: Preferir imágenes oficiales, estables y específicas para cada etapa.
Cómo integrar Multi-Stage Build en flujos DevOps y CI/CD
Las Multi-Stage Build son especialmente útiles en pipelines de integración y entrega continua. Algunas recomendaciones al integrarlas:
- Configurar caché compartido en pipelines para acelerar compilación incremental.
- Realizar análisis de seguridad y vulnerabilidades sobre las imágenes finales reducidas.
- Generar etiquetas/versiones de las imágenes basadas en semver, para facilitar gestión y despliegue.
- Automatizar tests al final de la build para validar que la imagen funciona correctamente.
- Separar entornos de build y producción en la infraestructura para minimizar riesgos.
Integración con otras tecnologías: Kubernetes y orquestadores
Las imágenes optimizadas creadas con Multi-Stage Build son ideales para su uso en entornos de orquestación como Kubernetes. Al ser ligeras, se benefician de:
- Arranques más rápidos de pods.
- Reducción en uso de recursos en nodos.
- Menos datos transferidos en actualizaciones y despliegues.
Esto impacta positivamente en la escalabilidad y resiliencia de aplicaciones desplegadas.
Consejos para optimizar aún más tus Multi-Stage Builds
- Usa imágenes base minimalistas: Como Alpine Linux cuando sea posible, para reducir peso.
- Combina instrucciones RUN para minimizar capas.
- Evita copiar archivos innecesarios transferidos.
- Utiliza variables de entorno para parámetros reutilizables.
- Chequea el resultado con
docker image history
para entender las capas generadas.
Palabras clave relacionadas y su relevancia
Dockerfile
Archivo donde se definen las instrucciones para construir una imagen Docker. En Multi-Stage Build, se utiliza para definir múltiples etapas y coordinar la compilación y ejecución.
Contenedor
Unidad estandarizada que despliega aplicaciones con sus dependencias. Docker permite ejecutar contenedores a partir de imágenes construidas, facilitando la portabilidad.
SDK
Kit de desarrollo que incluye compiladores, librerías y herramientas necesarias para crear software. Se usa en la primera etapa de una Multi-Stage Build.
Runtime
Entorno de ejecución necesario para ejecutar el software compilado, pero sin las herramientas de desarrollo. La imagen final utiliza solo el runtime.

Imagen Docker
Paquete ligero, independiente y ejecutable que contiene todo lo necesario para ejecutar una aplicación. El objetivo de Multi-Stage Build es optimizar su tamaño.
Contexto de build
Conjunto de archivos y rutas disponibles durante el proceso de construcción de la imagen. Se debe optimizar para evitar archivos inútiles que afecten el resultado.
Docker ignore
Fichero que lista archivos y carpetas que Docker debe ignorar en el contexto de build, ayudando a reducir el tamaño y tiempo de construcción.
Cache de Docker
Mecanismo que reutiliza capas previas para acelerar futuras builds. Ordenar instrucciones correctamente en un Dockerfile es esencial para aprovecharlo.
Te invitamos a complementar esta lectura con nuestro video explicativo, donde se profundiza en las ventajas y ejemplo práctico de Multi-Stage Builds:
Preguntas frecuentes (FAQ)
¿Por qué mi imagen con Multi-Stage Build sigue siendo demasiado grande?
Esto puede deberse a que la etapa final utiliza una imagen base pesada. Opta por imágenes base minimalistas como Alpine o slim. Además, verifica que no se copien archivos innecesarios y que no existan cachés o depuradores incluidos.
¿Puedo usar Multi-Stage Build con otros lenguajes y frameworks?
Sí, Multi-Stage Build es una práctica universal para Docker y funciona con cualquier lenguaje o framework que requiera etapas de compilación y ejecución separadas, como Java, Node.js, Go, Python, entre otros.
¿Cómo puedo depurar un Dockerfile con múltiples stages?
Una técnica útil es construir stages individuales utilizando la opción --target
de Docker build para enfocarte en etapas específicas y detectar problemas. También puedes agregar comandos intermedios para inspeccionar el contenido de directorios.
¿Es necesario tener Docker instalado para ejecutar estas imágenes?
Sí, aunque la ventaja es que no necesitas tener instalado el SDK o entorno de desarrollo del lenguaje, la ejecución de la imagen Docker requiere Docker en la máquina del usuario.

¿Qué diferencias hay entre CMD y ENTRYPOINT en un Dockerfile multistage?
CMD establece parámetros por defecto que pueden ser sobrescritos al ejecutar el contenedor. ENTRYPOINT configura el ejecutable principal que siempre se corre. Se recomienda usar ENTRYPOINT para comandos esenciales y CMD para argumentos configurables.
¿Cómo controlar las versiones de imágenes base en Multi-Stage Build?
Para garantizar estabilidad y seguridad, es recomendable fijar versiones concretas o etiquetas en las imágenes base. Por ejemplo, usar dotnet/sdk:8.0.5
en lugar de dotnet/sdk:latest
.
¿Qué sucede si copio una carpeta demasiado grande entre stages?
El tamaño de la imagen final crecerá considerablemente, ya que todos los archivos copiados en la etapa final forman parte de la imagen. Se recomienda copiar solo lo estrictamente necesario para la ejecución.
¿Se puede compartir volúmenes entre stages en lugar de copiar ficheros?
Docker build no permite montar volúmenes entre stages. El método correcto para compartir artefactos entre stages es mediante la instrucción COPY --from
. Montar volúmenes es una operación de ejecución del contenedor, no de construcción.
Preguntas obligatorias con respuestas extensas
¿Cómo Multi-Stage Build mejora la eficiencia en el desarrollo y despliegue de aplicaciones?
Multi-Stage Build separa claramente el proceso de compilación y el de ejecución, permitiendo utilizar imágenes base especializadas para cada tarea. Esto reduce dramáticamente el tamaño de la imagen final, minimiza las dependencias en producción y acelera tanto el despliegue como los tiempos de transferencia. La modularidad que aporta, significa menos errores, mayor seguridad al eliminar herramientas innecesarias y una gestión más sencilla de las imágenes.
¿Qué diferencias hay en el manejo de dependencias entre una build tradicional y una Multi-Stage Build?
En la build tradicional, el contenedor incluye tanto las herramientas de compilación como las dependencias de ejecución, lo que genera imágenes pesadas. Con Multi-Stage Build, las dependencias de compilación se usan solo durante la fase de construcción y no quedan en la imagen final. Solo las dependencias runtime necesarias se mantienen, optimizando espacio y mejorando cambios en producción de forma más controlada.
¿Cuándo no conviene usar Multi-Stage Build?
Aunque Multi-Stage Build es muy beneficioso, en proyectos extremadamente simples donde el contexto y la imagen final no sufren mucho, puede no justificar la complejidad añadida. También en casos donde las herramientas de compilación deben estar presentes en producción para tareas específicas puede estar contraindicado. Sin embargo, estos casos son poco frecuentes y en la mayoría de los escenarios modernos es una técnica recomendable.
Conclusión
El uso de Multi-Stage Build es indispensable para desarrollar contenedores Docker eficientes, seguros y fáciles de mantener. Esta técnica no solo reduce el tamaño de las imágenes y mejora el tiempo de despliegue, sino que también garantiza que las aplicaciones sean portables y ejecutables en cualquier entorno con Docker instalado, sin necesidad de contar con el SDK o herramientas adicionales.
Para equipos de desarrollo y operaciones, integrar Multi-Stage Build dentro de pipelines CI/CD y workflows DevOps es una práctica recomendada que aporta beneficios claros y medibles.

¿Querés mantenerte actualizado con las últimas tendencias en automatización, inteligencia artificial y transformación digital? Visitá nuestro blog de Código6 y descubrí guías, casos de éxito y noticias relevantes para potenciar tu empresa. Ingresá al blog y explorá los recursos más recientes.
Leave A Comment