Saltar a contenido

Dockerización Multi-Stage

Tarea a realizar

Separar el proceso de dockerización anterior en 2 fases:

  1. Build(construcción)

    • Generar la web (site/)
  2. Run (producción)

    • Solo sirve la web estática
    • ❌ sin Python
    • ❌ sin mkdocs/zensical
    • ❌ sin código fuente

¿Qué es la dockerización?

En lugar de meter todo (herramientas de compilación + app final) como haces en la dockerización normal, en una sola imagen, pues haces algo así:

  1. 🔧 Stage de build: Incluye compiladores, dependencias pesadas, etc. (solo para construir la app).
  2. 📦 Stage final: Copias solo lo necesario (el resultado ya compilado) a una imagen mucho más ligera.

¿Para que sirve?

  • Reducir tamaño de la imagen (mucho más ligera)
  • Mejorar seguridad (sin herramientas innecesarias)
  • Optimizar despliegue (descargas más rápidas)
  • Mantener limpio el entono final

Ejemplo:

# Stage 1: build
FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build

# Stage 2: producción
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html

Aquí:

  • El primer Stage contruye la app
  • El segundo solo copia el resultado final

Estructura 🏗

proyecto/
├── docs/
|   ├── index.md    
|   └── ...         <-- (los demás archivos que tengas)
├── mkdocs.yml
├── requirements.txt
└── Dockerfile      <-- (hay que crearlo, pero ahora el multi-stage)

Dockerfile

El archivo que tenemos q crear contendrá lo siguiente:

Puedes ayudarte de la guía haciendo clic en el enlace.

dockerfile
################################################
################ Stage 1: Build ################
################################################

# Usamos una imagen con Python para generar la documentación
FROM python:3.14-alpine AS builder

# Directorio de trabajo dentro del contenedor
WORKDIR /app

#Copiamos el proyecto 
COPY . .

# Instalamos el fichero requirements.txt con todo lo necesario
RUN pip install -r requirements.txt

#Generamos la web estática
RUN zensical build

################################################
############# Stage 2: Producción ##############
################################################

# Usamos Nginx para servir el contenido estático
FROM nginx:alpine

# Eliminamos la web por defecto de Nginx
RUN rm -rf /usr/share/nginx/html/*

# Copiamos SOLO la web generada desde la fase anterior
COPY --from=builder /app/site /usr/share/nginx/html

# Exponemos el puerto 8086 para servir la documentación
EXPOSE 8086

# Arrancamos Nginx
CMD ["nginx", "-g", "daemon off;"]

En cuanto al requirements.txt en mi caso lo tendría de la siguiente forma, lo más importante aquí es que tengamos el zensical para q no haya problemas.

requirements.txt
zensical
mkdocs-glightbox

Dockerización.

Contruimos la imagen con

cd ruta/proyecto
docker build -t [Nombre-imgen] .
Imagen

docker build

Ejecutamos el contenedor en nuestro caso 8086:80

  • 8086 porque es el que hemos especificado en el archivo Dockerfile "EXPOSE 8086"
  • 80 porque es en el que sirve el contenedor de nginx por defecto y no lo hemos cambiado
docker run -p PUERTO_PC:PUERTO_CONTENEDOR [nombre-imagen]
Imagen

docker run

Comprobamos que funciona correctamente accediendo por el puerto que especificamos http://localhost:8086

comprobación