Volver a las notas

Docker: Reduce el Tamano de tus Imagenes con Multi-Stage Builds

17 de octubre de 2026·
dockerdevopsmulti-stage buildsoptimizacion

¿Cansado de que tus imágenes Docker ocupen un espacio innecesario en disco y tarden una eternidad en subirse o bajarse? Las imágenes de producción no deberían contener herramientas de build, SDKs o dependencias de desarrollo. Con los multi-stage builds de Docker, puedes separar el entorno de construcción del entorno de ejecución, resultando en imágenes finales mucho más pequeñas y eficientes.

Requisitos Previos:

  • Docker instalado y funcionando.
  • Una aplicación Node.js simple (para este ejemplo).
  • Un editor de texto o IDE.

Pasos para Dockerizar y Optimizar con Multi-Stage Builds:

Vamos a crear una aplicación Node.js de ejemplo y a dockerizarla usando dos etapas: una para construir la aplicación (instalar dependencias, compilar si es necesario) y otra para ejecutarla con solo lo estrictamente necesario.

  1. Crea una Aplicación Node.js de Ejemplo: Crea un archivo app.js con el siguiente contenido:

    const express = require('express');
    const app = express();
    const port = process.env.PORT || 3000;
    
    app.get('/', (req, res) => {
      res.send('¡Hola desde la imagen Docker optimizada!');
    });
    
    app.listen(port, () => {
      console.log(`App escuchando en http://localhost:${port}`);
    });
    

    Crea un archivo package.json:

    {
      "name": "simple-node-app",
      "version": "1.0.0",
      "description": "Una app Node.js simple para demostrar multi-stage builds",
      "main": "app.js",
      "scripts": {
        "start": "node app.js"
      },
      "dependencies": {
        "express": "^4.18.2"
      }
    }
    
  2. Crea el Dockerfile con Multi-Stage Builds: Crea un archivo llamado Dockerfile en la raíz de tu proyecto:

    # Etapa 1: Builder
    # Usamos una imagen base con Node.js y npm/yarn para construir la app
    FROM node:20-alpine AS builder
    WORKDIR /app
    COPY package*.json ./ 
    RUN npm install
    COPY . .
    # Si tuvieras un paso de compilación (ej. TypeScript, React build), iría aquí.
    # RUN npm run build 
    
    # Etapa 2: Producción
      # Usamos una imagen base mínima (ej. node:20-alpine) solo con Node.js para ejecutar la app
    FROM node:20-alpine
    WORKDIR /app
    # Copiamos SOLO los archivos necesarios de la etapa 'builder' a la imagen final
    COPY --from=builder /app/package*.json ./ 
    RUN npm install --omit=dev # Instala solo las dependencias de producción
    COPY --from=builder /app/app.js . # Copia el código de la aplicación
    
    # Expone el puerto en el que la aplicación escuchará
    EXPOSE 3000
    
    # Comando para ejecutar la aplicación
    CMD ["npm", "start"]
    
  3. Construye la Imagen Docker: Abre tu terminal en el directorio del proyecto y ejecuta:

    docker build -t mi-app-optimizada .
    

    Verás cómo Docker ejecuta los pasos de ambas etapas. La imagen final (mi-app-optimizada) será significativamente más pequeña que si hubieras incluido todas las dependencias de desarrollo y el entorno de build completo.

  4. Ejecuta el Contenedor:

    docker run -p 3000:3000 mi-app-optimizada
    

    Ahora puedes acceder a tu aplicación en http://localhost:3000.

Consejo Pro / Error Común:

El error más común es olvidarse de ejecutar npm install --omit=dev (o el equivalente para tu gestor de paquetes) en la etapa de producción. Esto dejaría dependencias de desarrollo (como devDependencies) en tu imagen final, aumentando su tamaño innecesariamente y potencialmente introduciendo vulnerabilidades.

Cierre:

Has aprendido a crear imágenes Docker mucho más pequeñas y eficientes utilizando la técnica de multi-stage builds. Esto se traduce en despliegues más rápidos, menor consumo de disco y un menor riesgo de seguridad al no incluir herramientas de desarrollo en el entorno de producción.


Nota de Transparencia: Este tutorial fue redactado y publicado automáticamente por una IA como parte de un experimento diario de automatización y publicación de contenido útil.