BookinglyTech News
Infraestructura

Un contenedor Python pasa de 1,8 GB a 60 MB con distroless y build multi-etapa

Reescribir el Dockerfile en dos etapas y quedarse con una imagen distroless recorta el peso un 96% y borra el ruido de vulnerabilidades del sistema operativo. El precio es quedarse sin shell.

2 min de lecturar/selfhosted0 vistas

Una API Python que corría sobre una imagen base ubuntu:22.04 pesaba 1,8 GB. Después de reescribir el Dockerfile como build multi-etapa y quedarse con una imagen distroless, el contenedor resultante ocupa 60 MB y los escaneos con Trivy no devuelven ningún hallazgo a nivel de sistema operativo. La reducción es del 96%, y quien cuenta el caso lo atribuye a tres cosas: herramientas de sistema, dependencias de compilación y caché residual que arrastraba la imagen original.

El Dockerfile nuevo tiene dos etapas. La primera, la de compilación, parte de python:3.11-slim e instala las dependencias en el espacio de usuario. La segunda, la de ejecución, es gcr.io/distroless/python3-debian12 y ahí solo se copian /root/.local y el código fuente. Todo lo que hacía falta para construir se queda fuera de la imagen final.

Lo que se pierde

El problema aparece en el día a día, no en la build. Una imagen distroless no trae shell: no hay sh ni bash, así que el docker exec de toda la vida para entrar a mirar qué pasa deja de funcionar. En staging se nota más que en producción, porque es donde uno suele ir a hurgar.

La pregunta que lanza quien comparte el caso es justo esa: para quien corre distroless en producción, ¿la depuración se resuelve con sidecars de debug y contenedores efímeros, o se asume que solo hay telemetría y logs y se trabaja a ciegas cuando algo se rompe?

Las dos vías existen. Los contenedores efímeros permiten inyectar un proceso de diagnóstico en un pod en marcha sin reiniciarlo, y los sidecars de depuración hacen algo parecido de forma más permanente. Ninguna de las dos es gratis: hay que tenerlas previstas en el manifiesto y en los permisos del clúster antes de necesitarlas, y ninguna te da exactamente la comodidad de un shell dentro del contenedor original.

El interés del caso no está en la técnica, que lleva años documentada, sino en el número. Pasar de casi dos gigas a 60 MB significa imágenes que se descargan y se arrancan más rápido, menos superficie de ataque que parchear y menos CVE de sistema operativo llegando al panel de turno. Para cualquiera que mueva muchos pods, eso se nota en el registro y en el tiempo de despliegue.

Lo que no hay es una respuesta cerrada sobre la depuración, y el autor del mensaje tampoco la da. Quien haya tenido que diagnosticar un contenedor sin shell a las tres de la mañana sabe que la diferencia entre tener un sh y no tenerlo no se ve en el escaneo de vulnerabilidades. Se ve cuando algo falla.