Construyendo Imágenes Docker Multi-Versión con Docker Buildx Bake

Soy Roxs 👩💻| Software Developer | DevOps | DevSecOps | en @295DevOps 🖼 Content Creator. No se puede crecer si no estas dispuesto a saltar a la zona de peligro 🔥
En el mundo de los contenedores, el tamaño importa. Las imágenes Alpine Linux son conocidas por ser extremadamente ligeras y seguras, lo que las hace ideales para entornos de producción. En este artículo, exploraremos cómo crear y mantener múltiples versiones de imágenes Python basadas en Alpine usando Docker Buildx Bake y GitLab CI.

Introducción
Las imágenes Alpine de Python ofrecen varias ventajas:
Tamaño reducido (~ 50-100MB vs 900MB+ en imágenes basadas en Debian)
Menor superficie de ataque para vulnerabilidades
Mejor rendimiento en entornos cloud
Inicio más rápido de contenedores
Estructura del Proyecto
.
├── Dockerfile
├── bake.hcl
└── .gitlab-ci.yml
El Dockerfile Base Optimizado
Crearemos un Dockerfile optimizado para Alpine que incluye las dependencias necesarias para la mayoría de aplicaciones Python:
ARG IMAGE=python:3.12-alpine
FROM $IMAGE
LABEL maintainer="roxs@295devops.com"
# Instalamos solo las dependencias básicas necesarias
RUN apk add --no-cache \
git \
gcc \
build-base
# Creamos y usamos usuario no root
RUN addgroup -S python && adduser -S python -G python
USER python
WORKDIR /app
Configuración de Bake para Imágenes Alpine
El archivo bake.hcl se configura específicamente para versiones Alpine:
variable "REGISTRY" {
default = "docker.io/tunombre/"
}
group "default" {
targets = ["py-3-12-alpine", "py-3-11-alpine", "py-3-10-alpine"]
}
target "py-3-12-alpine" {
dockerfile = "./Dockerfile"
tags = [
"${REGISTRY}python-alpine:3.12"
]
args = {
IMAGE = "python:3.12-alpine"
}
}
target "py-3-11-alpine" {
dockerfile = "./Dockerfile"
tags = ["${REGISTRY}python-alpine:3.11"]
args = {
IMAGE = "python:3.11-alpine"
}
}
target "py-3-10-alpine" {
dockerfile = "./Dockerfile"
tags = ["${REGISTRY}python-alpine:3.10"]
args = {
IMAGE = "python:3.10-alpine"
}
}
Configuración de GitLab CI
stages:
- build
.build:
image: docker:27.5.0
stage: build
variables:
DOCKER_HOST: "tcp://docker:2375"
DOCKER_TLS_CERTDIR: ""
BUILDX_NO_DEFAULT_ATTESTATIONS: 1
DOCKER_DRIVER: overlay2
DOCKER_BUILDKIT: 1
BUILDKIT_PROGRESS: plain
services:
- name: docker:27.5.0-dind
command: ["--tls=false"]
before_script:
- docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_TOKEN
- docker info
build:
extends: .build
parallel:
matrix:
- BUILD: ['py-3-12-alpine', 'py-3-11-alpine', 'py-3-10-alpine']
REGISTRY: ['docker.io/tunombre/']
script:
- docker buildx create --use
- REGISTRY=${REGISTRY} docker buildx bake --progress plain --push -f bake.hcl $BUILD
Usando las Imágenes Alpine
# Última versión
FROM tunombre/python-alpine:3.12
# Versiones específicas
FROM tunombre/python-alpine:3.11
FROM tunombre/python-alpine:3.10
Comparación de Tamaños
Aquí una comparación del tamaño de las imágenes:
Python Alpine: ~100MB
Python Slim: ~200MB
Python Regular: ~900MB
Consideraciones Importantes
Cuando uses imágenes Alpine, ten en cuenta:
Dependencias Nativas: Alpine usa musl libc en lugar de glibc, lo que puede causar problemas con algunas dependencias nativas.
Paquetes del Sistema: Los nombres de los paquetes pueden diferir de Debian/Ubuntu.
Compilación: Algunas dependencias pueden requerir compilación, por lo que necesitarás incluir
build-basey otras herramientas de compilación.
Construcción Local
# Construir todas las versiones
docker buildx bake -f bake.hcl
# Construir una versión específica
docker buildx bake -f bake.hcl py-3-12-alpine
# Construir y publicar
REGISTRY=docker.io/tunombre/ docker buildx bake --push -f bake.hcl
Optimizaciones Adicionales
- Multi-stage Builds: Para reducir aún más el tamaño:
# Etapa de construcción
FROM python:3.12-alpine AS builder
RUN apk add --no-cache build-base
RUN pip install --no-cache-dir mypackage
# Etapa final
FROM python:3.12-alpine
COPY --from=builder /usr/local/lib/python3.12/site-packages/ /usr/local/lib/python3.12/site-packages/
Cache de pip: Usar
--no-cache-dirpara reducir el tamaño de la imagen.Limpieza: Eliminar archivos innecesarios después de la instalación.
Resultado


Si quiero ejecución manual usen en gitlab-ci when:manual
build:
extends: .build
when:manual
parallel:
matrix:
- BUILD: ['py-3-12-alpine', 'py-3-11-alpine', 'py-3-10-alpine']
REGISTRY: ['docker.io/tunombre/']
script:
- docker buildx create --use
- REGISTRY=${REGISTRY} docker buildx bake --progress plain --push -f bake.hcl $BUILD

Conclusión
Las imágenes Alpine ofrecen un excelente equilibrio entre tamaño y funcionalidad. Con Docker Buildx Bake y GitLab CI, podemos mantener fácilmente múltiples versiones de estas imágenes optimizadas.
La configuración que hemos cubierto permite:
Crear imágenes Python ligeras y seguras
Mantener múltiples versiones de forma automatizada
Optimizar el proceso de construcción y distribución






