Reducir el tamaño de imágenes Docker es una de esas optimizaciones que parecen menores hasta que ves la factura de la nube. Aquí aprendes a bajar una imagen de .NET de 1,19 GB a 126 MB usando una distribución base distinta y reglas claras para decidir cuándo conviene cada opción.
¿Por qué importa tanto el tamaño de una imagen Docker?
Cuando despliegas un sistema distribuido, cada megabyte cuenta. Una imagen de 1,1 GB en tu disco no parece grave, pero multiplícala por 150 servicios subidos a la nube y la cuenta se vuelve seria.
El tamaño afecta tres cosas concretas:
- El costo de almacenamiento y transferencia en la nube.
- La velocidad con la que tus contenedores arrancan y se replican.
- El consumo de recursos en tu pipeline de CI/CD.
Por eso, optimizar el peso no es un capricho estético. Es una decisión de arquitectura.
¿Cómo se compara una imagen Docker estándar contra una Alpine?
Para mostrar la diferencia, partimos de un proyecto nuevo de .NET, que de fábrica genera imágenes pesadas. Es un caso ideal porque vas a ver el contraste sin matices [01:30].
¿Qué pasa con la imagen base por defecto?
El primer Dockerfile usa la imagen sdk 8.0 estándar. El flujo es el típico: defines un directorio de trabajo (yo suelo llamarlo src), copias el dependencies.csproj, ejecutas dotnet publish y luego usas la imagen de runtime para correr la DLL.
Un detalle práctico que vale recordar: el archivo Dockerfile puede escribirse con mayúscula o minúscula sin problema. Tanto Visual Studio Code como Docker lo reconocen igual [02:45].
Después de correr docker build -t dependencias ., la imagen resultante pesa 1,19 GB. Funciona, pero es enorme.
¿Qué es una imagen base en Docker? Es la capa inicial sobre la que se construye tu contenedor. Define el sistema operativo y las herramientas disponibles. Elegirla bien marca la diferencia entre una imagen de 1 GB y una de 100 MB.
¿Cómo cambia el resultado al usar Alpine?
En la segunda iteración, modificas dos cosas en el Dockerfile:
- Cambias
sdk 8.0 por sdk 8.0-alpine.
- Usas también
runtime 8.0-alpine en la etapa final.
Alpine es una distribución de Linux muy básica, sin paquetes que tu aplicación probablemente no necesite. Eso permite contraer pasos del Dockerfile y reducir capas.
Al reconstruir la imagen con el mismo comando, el resultado es 126 MB, casi diez veces más liviana que la versión anterior [05:50]. Mismo proyecto, mismo comportamiento, una fracción del peso.
¿Cuándo conviene usar Alpine y cuándo no?
Reducir el tamaño no siempre es la mejor decisión. Hay tres reglas que seguimos en los proyectos dentro de Microsoft para decidir qué imagen base usar.
- Regla uno: entre más pequeña sea tu imagen, mejor para tu sistema. Menos peso significa menos costo y más velocidad.
- Regla dos: nunca sacrifiques el rendimiento de tu aplicación. Si una imagen más liviana hace que tu app responda lento, no vale la pena.
- Regla tres: nunca sacrifiques la seguridad. Aunque tu imagen sea pequeña y rápida, si abre puertas que no debe, perdiste.
Esto significa que a veces aceptas una imagen grande porque el proyecto lo exige. Otras veces, Alpine funciona de maravilla porque la aplicación es pequeña y autocontenida. Cada escenario pide una decisión distinta.
¿Qué es Alpine Linux en Docker? Es una distribución de Linux mínima usada como imagen base. Pesa pocos megabytes porque incluye solo lo esencial, lo que reduce drásticamente el tamaño final del contenedor.
¿Qué patrón seguir al escribir un Dockerfile optimizado?
La estructura que usamos en el ejemplo aplica el patrón de multi-stage build: una etapa con el SDK para compilar y publicar, y otra etapa más liviana solo con el runtime para ejecutar.
dockerfile
FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build
WORKDIR /app
COPY . ./
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine
WORKDIR /app
COPY --from=build /app/out .
ENTRYPOINT ["dotnet", "dependencies.dll"]
La clave está en que la imagen final no carga el SDK, solo el runtime. Y al combinarlo con alpine, recortas todavía más.
Un detalle: si usas Python en lugar de .NET, probablemente bajes de 300 MB a 150 MB. No es espectacular, pero es ganancia. Con .NET, el salto de 1,19 GB a 126 MB sí cambia las reglas del juego.
¿Has medido el peso de tus imágenes en producción? Cuéntame en los comentarios qué tamaños manejas y qué imagen base sueles elegir.