Programa
Docker Buildx: Cómo crear imágenes de contenedores multiplataforma
Construir contenedores para múltiples plataformas suena intimidante y requiere mucho tiempo, pero estás a punto de ver que en realidad no lo es.
El comando docker buildx
resuelve este reto ampliando las capacidades de compilación de Docker con funciones avanzadas como la creación de imágenes multiplataforma, el almacenamiento en caché mejorado y el procesamiento de compilación en paralelo. Integra el motor de compilación de nueva generación BuildKit directamente en la CLI de Docker. Con el comando buildx
, crearás imágenes de contenedores más pequeñas, rápidas y seguras sin aprender un conjunto de herramientas totalmente nuevo.
En los últimos años, Buildx se ha vuelto más o menos esencial para las mejores prácticas DevOps y el desarrollo de aplicaciones nativas de la nube. Agiliza los procesos CI/CD y te ayuda a ti y a tu equipo a entregar aplicaciones de forma coherente en diversos objetivos de despliegue, desde dispositivos IoT basados en ARM hasta granjas de servidores en la nube.
> ¿Eres nuevo en Docker? Nuestra guía práctica para principiantes te ayudará a empezar en un abrir y cerrar de ojos.
En este artículo, te guiaré a través de las técnicas principiantes y avanzadas de docker buildx
.
Comprender Docker Buildx
Probablemente ya utilices Docker, así que conoces el comando estándar docker build
. Sin embargo, tarde o temprano empezarás a sentirte limitado, sobre todo cuando tus proyectos se vuelvan más complejos.
> Docker Buildx asume que tienes instalado Docker. Si no lo tienes, y estás ejecutando gLinux, sigue esta guía para una instalación sencilla.
Docker Buildx te ofrece una experiencia de compilación mejorada que funciona con tus conocimientos actuales. No es una herramienta independiente que tengas que instalar: ya viene incluida con Docker Desktop y Engine desde la versión 19.03. Buildx utiliza BuildKit bajo el capó, que es el constructor de nueva generación de Docker que reescribe cómo se crean las imágenes. Notarás construcciones más rápidas, imágenes más pequeñas y compatibilidad con funciones adicionales.
El salto de docker build
a docker buildx build
puede parecer pequeño -al fin y al cabo es sólo una palabra-, pero las capacidades que ganas son enormes.
Exploremos cómo funciona realmente Buildx y qué lo diferencia del constructor heredado.
Fundamentos arquitectónicos de Buildx
La magia de Buildx proviene de su inteligente diseño cliente-servidor.
Cuando ejecutas un comando Buildx, estás utilizando la CLI de Docker como cliente que se comunica con el demonio BuildKit, el componente servidor que se encarga del trabajo pesado. Esta separación permite a BuildKit hacer cosas que el constructor heredado no puede, como ejecutar etapas de construcción en paralelo en lugar de secuencialmente. Las instrucciones de tu Dockerfile ya no tienen que ejecutarse una tras otra, lo que reduce significativamente los tiempos de compilación cuando tienes etapas independientes.
El modelo cliente-servidor también permite la ejecución remota de la construcción. Puedes dirigir tu CLI local de Docker a una instancia remota de BuildKit que se ejecute en cualquier lugar: en un servidor de compilación potente, en la nube o incluso en un clúster Kubernetes. Esta flexibilidad significa que no necesitas inmovilizar los recursos de tu portátil para construcciones masivas ni preocuparte por problemas de compatibilidad de arquitecturas.
El diseño modular de BuildKit también te permite conectar diferentes analizadores frontales. La sintaxis Dockerfile es la predeterminada, pero puedes utilizar formatos de definición de compilación alternativos si se adaptan mejor a tu flujo de trabajo.
Construye el flujo del proceso
Cuando ejecutas docker buildx build
, la CLI selecciona primero una instancia de constructor, que puede ser la predeterminada o la que hayas especificado. Tu contexto de construcción y tu archivo Docker se envían al demonio BuildKit, que analiza las instrucciones y crea un grafo acíclico dirigido (DAG) de pasos de construcción. A diferencia del constructor heredado, que procesa cada instrucción secuencialmente, BuildKit analiza este gráfico para determinar qué pasos pueden ejecutarse en paralelo.
A continuación, el constructor ejecuta estos pasos utilizando algoritmos de caché eficientes que son mucho más inteligentes que la antigua caché basada en capas. BuildKit rastrea las entradas y salidas exactas de cada paso, lo que evita reconstrucciones innecesarias cuando no ha cambiado nada relevante. También permite distribuir la compilación entre varios nodos de trabajo para un procesamiento aún más rápido.
Después de construir, Buildx puede exportar los resultados en diferentes formatos, no sólo como imágenes Docker. Puedes exportar a formatos OCI, directorios locales o tarballs, o incluso omitir por completo la creación de imágenes si sólo quieres probar el proceso de compilación.
Tienes razón, esta sección podría beneficiarse de más ejemplos prácticos y visuales para demostrar cómo funciona Buildx en situaciones reales. Así es como yo lo mejoraría con más ejemplos de código y sugerencias de imágenes:
Funciones y características básicas
Docker Buildx no se limita a crear imágenes más rápidamente, aunque sin duda lo hace. Se trata de ampliar las posibilidades de tus procesos de construcción.
Veamos las características más destacadas que hacen que merezca la pena considerar Buildx para tu próximo proyecto.
> ¿Buscas un proyecto Docker endeas? Estos 10 harán que tu portafolio DevOps esté en línea.
Aplicación Python utilizada
Para los fines de este artículo, he creado una sencilla aplicación Python Flask. Para seguir, crea 3 archivos - app.py
, requirements.txt
, y Dockerfile
.
Estos son los contenidos de cada uno:
app.py
from flask import Flask, render_template_string
import platform
import socket
import psutil
import datetime
app = Flask(__name__)
@app.route("/")
def home():
html = """
<!DOCTYPE html>
<html>
<head>
<title>Docker Buildx Python Demo</title>
<style>
body {
max-width: 800px;
}
.container {
border: 1px solid #ddd;
border-radius: 5px;
background-
}
.info {
}
.platform {
font-weight: bold;
}
</style>
</head>
<body>
<h1>Docker Buildx Multi-Platform Demo (Python)</h1>
<div class="container">
<div class="info">Hostname: {{ hostname }}</div>
<div class="info">Platform: <span class="platform">{{ os_platform }} ({{ architecture }})</span></div>
<div class="info">CPUs: {{ cpu_count }}</div>
<div class="info">Total Memory: {{ memory_mb }} MB</div>
<div class="info">Server Time: {{ server_time }}</div>
</div>
</body>
</html>
"""
return render_template_string(
html,
hostname=socket.gethostname(),
os_platform=platform.system(),
architecture=platform.machine(),
cpu_count=psutil.cpu_count(),
memory_mb=round(psutil.virtual_memory().total / (1024 * 1024)),
server_time=datetime.datetime.now().isoformat(),
)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
requisitos.txt
flask==3.1.0
psutil==7.0.0
Dockerfile
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 5000
CMD ["python", "app.py"]
Una vez hecho esto, abre una nueva ventana de Terminal y navega hasta la carpeta del proyecto.
Construcción de imágenes multiplataforma
Crear imágenes que funcionen en diferentes arquitecturas de CPU parece una pesadilla, pero Buildx lo hace sorprendentemente sencillo.
Echa un vistazo a este comando:
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest .
Imagen 1 - Utilizando Docker Buildx
En resumen, te permite crear imágenes para varias arquitecturas simultáneamente. Buildx maneja esto mediante tres enfoques inteligentes: puede utilizar QEMU para la emulación de arquitectura (permitiéndote construir imágenes ARM en una máquina x86), conectarse a nodos constructores nativos para cada plataforma de destino, o combinar ambos métodos para un rendimiento óptimo. El resultado es una lista de manifiestos multiarquitectura -a veces llamada "manifiesto gordo"- que contiene variantes de tu imagen para cada plataforma.
Si estás desplegando en entornos diversos, como instancias Graviton de AWS, clusters Raspberry Pi o infraestructuras mixtas, esta compatibilidad multiplataforma es crucial.
Estrategias mejoradas de almacenamiento en caché
Buildx transforma completamente el funcionamiento de la caché de construcción y, en general, hace que tus construcciones sean más rápidas.
El sistema implementa una estrategia de almacenamiento en caché de tres capas que va más allá del simple almacenamiento en caché de capas de las construcciones Docker tradicionales:
- Incrustación de caché en línea: En primer lugar, Buildx utiliza una caché en línea incrustada en tus imágenes, lo que te permite aprovechar las capas almacenadas en caché de construcciones anteriores incluso en entornos nuevos.
- Caché de construcción local: En segundo lugar, admite una caché de compilación local que se gestiona de forma inteligente en función de las entradas de instrucciones de compilación y no sólo de su orden.
- Almacenamiento en caché basado en el registro: En tercer lugar, ofrece un almacenamiento en caché basado en registros que te permite compartir la caché de construcción entre máquinas, perfecto para canalizaciones CI/CD o equipos distribuidos.
Con nuestra aplicación Python, vamos a ver cómo podemos utilizar estrategias de caché local:
# Create a directory for local cache
mkdir -p buildx-cache
# First build - export cache to local directory
docker buildx build --cache-to type=local,dest=./buildx-cache -t myapp:latest .
# Make a small change to app.py
echo "# Small comment change" >> app.py
# Second build - use the local cache
docker buildx build --cache-from type=local,src=./buildx-cache -t myapp:latest .
La segunda construcción será mucho más rápida porque reutiliza las capas almacenadas en caché de la primera construcción.
Imagen 2 - Estrategias de caché local
También puedes utilizar la caché en línea, que incorpora metadatos de caché en la propia imagen:
docker buildx build --cache-to type=inline -t myapp:latest .
Puedes configurar estos backends de caché con banderas sencillas como --cache-to
y --cache-from
, apuntando a directorios locales, repositorios de registro o incluso servicios de caché especializados. Esta flexibilidad significa que tus construcciones se mantienen rápidas en diferentes entornos sin sacrificar la reproducibilidad.
Elementos de seguridad
Buildx incluye herramientas que eliminarán las preocupaciones de seguridad de tus pensamientos.
Supongamos que tu aplicación Python necesita acceder a una API meteorológica durante el proceso de construcción. En lugar de codificar tu clave API en el archivo Dockerfile, puedes utilizar secretos de compilación:
# Store your API key in a local file
echo "abc123yourweatherapikey" > ./api_key.txt
# Build with the secret
docker buildx build --secret id=weather_api_key,src=./api_key.txt -t myapp:latest .
Luego, en tu Dockerfile, podrás acceder al secreto sólo cuando sea necesario:
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
# Create a config file using the secret at build time
RUN --mount=type=secret,id=weather_api_key \
echo "WEATHER_API_KEY=$(cat /run/secrets/weather_api_key)" > .env
EXPOSE 5000
CMD ["python", "app.py"]
Puedes verificar que la clave API no está en la imagen final comprobando el historial de imágenes o ejecutando:
docker run --rm myapp:latest cat .env
Imagen 3 - Gestión de variables de entorno
En tu app.py
, podrías cargar la clave API así:
import os
from dotenv import load_dotenv
load_dotenv() # Load variables from .env file
api_key = os.getenv("WEATHER_API_KEY", "")
# ...
Este enfoque significa que tu clave sensible de la API sólo está disponible durante el paso específico de construcción en el que se necesita, pero no se guarda en ninguna de las capas de la imagen. Cualquiera que extraiga tu imagen no podrá extraer tu clave API, aunque inspeccione las capas de la imagen.
Para mayor seguridad, también puedes utilizar contenedores de compilación temporales que se eliminan automáticamente después de la compilación:
docker buildx build --secret id=weather_api_key,src=./api_key.txt --rm -t myapp:latest .
La bandera --rm
se asegura de que se elimine cualquier contenedor intermedio creado durante el proceso de construcción, reduciendo aún más el riesgo de filtración de credenciales.
Configuración operativa
Configurar Buildx para tu flujo de trabajo sólo requiere unos pocos comandos, pero entender las opciones te ayudará a sacarle el máximo partido.
Vamos a ver cómo puedes configurar y gestionar Buildx en un entorno local para adaptarlo a tus necesidades específicas.
Gestión de instancias constructoras
Docker Buildx utiliza el concepto de "constructores": instancias BuildKit independientes con diferentes capacidades y configuraciones. Puedes crear varios constructores para distintos fines.
Primero, veamos qué constructores tienes ya:
docker buildx ls
Verás un resultado similar a éste:
Imagen 4 - Constructores disponibles
Para crear una nueva instancia de constructor, ejecuta los siguientes comandos:
# Create a new builder
docker buildx create --name mybuilder
# Switch to using that builder
docker buildx use mybuilder
# Bootstrap the builder (start it)
docker buildx inspect --bootstrap
Puedes verificar que funciona con
# Check the status
docker buildx ls
Imagen 5 - Cambiar a un constructor personalizado
Si necesitas eliminar un constructor, sólo tienes que ejecutar lo siguiente:
docker buildx rm mybuilder
Manipulación de la salida
Buildx te da opciones flexibles sobre qué hacer con las imágenes que construyes. Puedes cargarlos directamente en tu demonio Docker local, exportarlos como archivos tar o guardarlos en un directorio local.
Veamos cómo utilizar estas opciones con nuestra aplicación Python:
# Load the image directly into Docker (default behavior)
docker buildx build --load -t myapp:latest .
# Export the image as a tarball
docker buildx build --output type=docker,dest=myapp.tar -t myapp:latest .
# Save the image contents to a local directory
docker buildx build --output type=local,dest=./image-output -t myapp:latest .
Después de utilizar la exportación del tarball, puedes cargarlo en Docker con:
docker load < myapp.tar
Imagen 6 - Cargar una imagen desde una exportación de un tarball
La salida del directorio local es especialmente útil para la inspección. Veamos lo que se crea:
ls -la ./image-output
Verás el sistema de archivos de la imagen en bruto:
Imagen 7 - Contenido de la exportación del directorio local
Incluso puedes ejecutar etapas de construcción específicas sin crear una imagen final. Esto es útil para depurar o probar los pasos de construcción:
# Create a multi-stage Dockerfile
cat > Dockerfile.multi << 'EOF'
FROM python:3.13-slim AS base
WORKDIR /app
COPY requirements.txt .
FROM base AS dev-deps
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install pytest
FROM base AS prod-deps
RUN pip install --no-cache-dir -r requirements.txt
FROM prod-deps AS final
COPY app.py .
EXPOSE 5000
CMD ["python", "app.py"]
EOF
# Build only the dev-deps stage and export its filesystem
docker buildx build --file Dockerfile.multi --target dev-deps --output type=local,dest=./dev-deps-output .
Ahora puedes inspeccionar qué paquetes se instalaron en el entorno dev:
cat ./dev-deps-output/usr/local/lib/python3.13/site-packages/pytest/__init__.py
Imagen 8 - Contenido de los archivos de la etapa dev-deps
En resumen, estas opciones de salida te dan un control total sobre dónde van tus imágenes construidas, tanto si estás depurando localmente como si estás preparando imágenes para compartirlas con tu equipo.
Domina Docker y Kubernetes
Casos prácticos avanzados
Hasta ahora, te he mostrado comandos básicos de Buildx y casos de uso. Buildx puede hacer muchas más cosas, y algunas de las funciones son imposibles de implementar con el constructor clásico.
Exploremos algunas técnicas avanzadas para llevar tu flujo de trabajo de contenerización al siguiente nivel.
Optimización de la construcción en varias fases
Las compilaciones multietapa son una de las características más potentes de Docker para crear imágenes eficientes, y Buildx las hace aún mejores.
Para demostrarlo, vamos a crear una aplicación Python optimizada con varias etapas:
# Dockerfile.optimized
FROM python:3.13-slim AS base
WORKDIR /app
COPY requirements.txt .
FROM base AS builder
RUN pip install --no-cache-dir --target=/install -r requirements.txt
FROM base AS linter
COPY --from=builder /install /usr/local/lib/python3.13/site-packages
COPY app.py .
RUN pip install pylint && pylint app.py || exit 0
FROM base AS tester
COPY --from=builder /install /usr/local/lib/python3.9/site-packages
COPY app.py .
RUN pip install pytest && python -m pytest app.py -v || exit 0
FROM python:3.13-alpine AS final
WORKDIR /app
COPY --from=builder /install /usr/local/lib/python3.13/site-packages
COPY app.py .
EXPOSE 5000
CMD ["python", "app.py"]
Con Buildx, puedes construirlo de forma más eficiente:
docker buildx build --file Dockerfile.optimized -t myapp:optimized --load .
Imagen 9 - Construcciones multietapa
Entonces, ¿qué lo hace especial? Buildx procesa etapas independientes en paralelo. Mientras que el constructor heredado ejecutaría cada etapa secuencialmente, Buildx identifica que las etapas linter
y tester
no dependen unas de otras y las construye simultáneamente.
Otra ventaja añadida de esta optimización de la construcción es la reducción del tamaño del archivo. Puedes verificar el tamaño de la imagen ejecutando lo siguiente:
docker images myapp
Verás algo así:
Imagen 10 - Tamaños de imagen Docker
La imagen final alpina es mucho más pequeña.
Integración de tuberías CI/CD
Mientras trabajas localmente, puedes establecer configuraciones de Buildx que reflejen tu entorno CI/CD.
Para empezar, crea un archivo .dockerignore
para mantener limpias las construcciones:
.git
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env
venv
*.so
.coverage
htmlcov
A continuación, crea una secuencia de comandos de compilación que imite lo que podría hacer tu canalización CI:
#!/bin/bash
# build.sh - Local CI/CD simulation
echo "Starting CI/CD build process..."
# Setup builder with emulation support
echo "Setting up builder..."
docker buildx create --name cibuilder --use || true
docker buildx inspect --bootstrap
# Run linting
echo "Running lint stage..."
docker buildx build --file Dockerfile.optimized --target linter .
# Run tests
echo "Running test stage..."
docker buildx build --file Dockerfile.optimized --target tester .
# Build for multiple platforms
echo "Building multi-platform image..."
docker buildx build --file Dockerfile.optimized \
--platform linux/amd64,linux/arm64 \
--tag myapp:$(date +%Y%m%d) \
--tag myapp:latest \
--load \
--progress=plain \
.
echo "Build process complete!"
En pocas palabras, este script hace lo siguiente:
- Crea un constructor dedicado para CI/CD.
- Ejecuta la fase de pelusa.
- Ejecuta la fase de prueba.
- Construye la imagen final multiplataforma con etiquetas versionadas.
Ahora viene la parte divertida: haz que el script sea ejecutable y ejecútalo:
chmod +x build.sh
./build.sh
Edición local
Un punto doloroso habitual al trabajar con Docker es que cada vez que cambias el archivo fuente, tienes que reconstruir la imagen y ejecutar el contenedor. Simplemente lleva demasiado tiempo.
Aquí está la buena noticia: para el desarrollo local con iteraciones más rápidas, puedes crear una versión de desarrollo:
# Dockerfile.dev
FROM python:3.13-slim
WORKDIR /app
RUN pip install flask psutil python-dotenv
# Install development tools
RUN pip install pytest pylint watchdog
# Mount app code at runtime instead of copying
CMD ["python", "app.py"]
Ejecútalo con un montaje de volumen para recargar el código en vivo:
docker buildx build -f Dockerfile.dev -t myapp:dev --load .
docker run -it --rm -p 5000:5000 -v $(pwd):/app myapp:dev
Ahora puedes editar tu archivo app.py
localmente, ¡y los cambios se reflejarán inmediatamente en el contenedor en ejecución!
A continuación, hablemos del rendimiento.
Consideraciones sobre el rendimiento
A nadie le gusta un flujo de trabajo de desarrollo lento, y la potencia de la paralelización con Docker Buildx puede ayudar.
Exploremos cómo optimizar tus construcciones y aprovechar las funciones de rendimiento de Buildx para crear imágenes más rápidamente.
Construye técnicas de paralelización
Una de las mayores ventajas de Buildx es su capacidad para construir etapas en paralelo. El constructor de Docker tradicional ejecuta cada paso secuencialmente, pero Buildx analiza tu Dockerfile e identifica qué pasos pueden ejecutarse al mismo tiempo.
Para demostrarlo, utilizaré dos archivos: Dockerfile.standard
y Dockerfile.parallel
. Aquí tienes el contenido de ambos:
Dockerfile.estándar
FROM python:3.13-slim
WORKDIR /app
# System dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
g++ \
&& rm -rf /var/lib/apt/lists/*
# Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Application code
COPY app.py .
# Linting
RUN pip install pylint && pylint app.py || true
EXPOSE 5000
CMD ["python", "app.py"]
Dockerfile.parallel
FROM python:3.13-slim AS python-base
WORKDIR /app
# Independent stage for installing system dependencies
FROM python-base AS system-deps
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
g++ \
&& rm -rf /var/lib/apt/lists/*
# Independent stage for installing Python dependencies
FROM python-base AS python-deps
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Independent stage for static code analysis
FROM python-deps AS linting
COPY app.py .
RUN pip install pylint && pylint app.py || true
# Final stage that combines dependencies
FROM python-base AS final
# Copy from system deps stage
COPY --from=system-deps /usr/bin/gcc /usr/bin/gcc
# Copy from Python deps stage
COPY --from=python-deps /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
COPY app.py .
EXPOSE 5000
CMD ["python", "app.py"]
Midamos cómo esta estructura paralela mejora los tiempos de construcción:
# Time the standard sequential build
time docker build -t myapp:standard -f Dockerfile.standard .
# Time the parallel-optimized build with Buildx
time docker buildx build --load -t myapp:parallel -f Dockerfile.parallel .
Como referencia, la compilación estándar tardó 18,48 segundos, ¡mientras que la compilación paralela tardó sólo 1,17 segundos!
Para mejorar aún más el rendimiento, puedes probar a utilizar las banderas --cache-from
y --cache-to
para aprovechar la caché de disco local:
# First build - create cache
docker buildx build --load -t myapp:latest --cache-to type=local,dest=./buildcache .
# Subsequent builds - use cache
docker buildx build --load -t myapp:latest --cache-from type=local,src=./buildcache .
También puedes limitar el tamaño del contexto con archivos .dockerignore
cuidadosos:
# Create a comprehensive .dockerignore
cat > .dockerignore << 'EOF'
.git
.github
.dockerignore
.pytest_cache
__pycache__
*.pyc
*.pyo
*.pyd
.Python
venv
env
node_modules
.coverage
htmlcov
.DS_Store
EOF
Resumiendo, estructurando tus archivos Docker con la paralelización en mente y aprovechando la caché avanzada de Buildx, pasarás menos tiempo esperando las compilaciones y más tiempo desarrollando funciones.
Integración del ecosistema
Docker Buildx no existe de forma aislada. Está diseñado para integrarse perfectamente con otras herramientas de tu entorno de desarrollo.
Exploremos cómo Buildx funciona con las herramientas locales de los programadores y hace que tu flujo de trabajo con contenedores sea más eficiente.
Construir clusters Kubernetes
Kubernetes ofrece potentes capacidades para ejecutar operaciones distribuidas Docker Buildx en un clúster. Al integrar Buildx con Kubernetes, puedes obtener construcciones más rápidas y resistentes que se adaptan a las necesidades de tu proyecto.
> ¿Eres nuevo en Kubernetes? En Kubernetes vs Docker: Diferencias que todo programador debe conocer post es tu próxima parada.
Utilizar Kubernetes para tu infraestructura de construcción ofrece un par de ventajas:
- Escala automática: Kubernetes puede escalar tus nodos constructores hacia arriba o hacia abajo en función de la demanda, asignando recursos de forma eficiente a través de tu clúster. Incluso puedes establecer reglas de autoescalado basadas en la utilización de la CPU.
- Optimización de recursos: La programación de Kubernetes garantiza que tus construcciones obtengan los recursos que necesitan sin sobrecargar los nodos individuales. Puedes establecer límites de recursos y peticiones para garantizar un rendimiento constante.
- Alta disponibilidad: Al distribuir las instancias de BuildKit entre varios nodos, tu infraestructura de compilación sigue estando disponible aunque fallen nodos individuales.
- Entornos coherentes: Todos los miembros del equipo se conectan a la misma infraestructura de compilación, eliminando los problemas de "funciona en mi máquina".
- Ejecución paralela: Las construcciones complejas con muchas etapas pueden ejecutarse en paralelo en varios nodos, reduciendo significativamente los tiempos de construcción. Un proyecto que podría tardar 15 minutos en construirse localmente podría completarse en 3-4 minutos cuando se distribuye.
Considera ésta una sección más "teórica", ya que profundizar en Kubernetes es un tema avanzado en sí mismo.
Para empezar, crea un archivo llamado buildkit-deployment.yaml
con el siguiente contenido:
apiVersion: apps/v1
kind: Deployment
metadata:
name: buildkit
namespace: buildkit
spec:
replicas: 3
selector:
matchLabels:
app: buildkit
template:
metadata:
labels:
app: buildkit
spec:
containers:
- name: buildkit
image: moby/buildkit:latest
args:
- --addr
- tcp://0.0.0.0:1234
ports:
- containerPort: 1234
securityContext:
privileged: true
---
apiVersion: v1
kind: Service
metadata:
name: buildkit
namespace: buildkit
spec:
type: ClusterIP
ports:
- port: 1234
targetPort: 1234
selector:
app: buildkit
El siguiente paso es aplicar este archivo a tu clúster Kubernetes:
kubectl create namespace buildkit
kubectl apply -f buildkit-deployment.yaml
Por último, conéctate a esta implantación desde tu máquina local:
docker buildx create --name k8s-builder \
--driver remote \
--driver-opt endpoint=tcp://<cluster-ip>:1234 \
--use
Y ya está, ¡ya puedes empezar!
Compatibilidad con plugins IDE
IDEs como Visual Studio Code ofrecen una excelente integración con Docker Buildx a través de su extensión Docker. Esta integración facilita la gestión de tus flujos de trabajo Buildx directamente desde tu entorno de desarrollo.
Para empezar a utilizar Docker Buildx en VS Code, instala la extensión "Docker" del marketplace de VS Code.
Una vez instalado, obtendrás varias funciones específicas de Buildx:
- Haz clic con el botón derecho en cualquier archivo Docker para ver un menú contextual con una opción "Construir imagen..." compatible con Buildx.
- Accede a los argumentos de construcción, objetivos de plataforma y opciones de salida a través de la interfaz de usuario.
- Capacidad para gestionar y cambiar entre diferentes instancias del constructor.
- Integración con el terminal VS Code para ejecutar comandos Buildx complejos.
Imagen 11 - Extensión Docker para VSCode
He aquí un ejemplo de personalización de las tareas de VS Code para utilizar Buildx creando un archivo .vscode/tasks.json
:
{
"version": "2.0.0",
"tasks": [
{
"label": "Docker: Buildx Build",
"type": "shell",
"command": "docker buildx build --load -t ${input:imageName} .",
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Docker: Buildx Multi-Platform",
"type": "shell",
"command": "docker buildx build --platform linux/amd64,linux/arm64 -t ${input:imageName} ."
}
],
"inputs": [
{
"id": "imageName",
"description": "Image name (with tag):",
"default": "myapp:latest",
"type": "promptString"
}
]
}
Con esta configuración, puedes acceder rápidamente a comandos Buildx comunes desde el menú Tareas de VS Code(Terminal > Ejecutar tarea). La extensión también proporciona un útil resaltado de sintaxis para archivos Docker y autocompletado para comandos Docker comunes, todo lo cual hace que tu flujo de trabajo Buildx sea más productivo.
Solución de problemas y depuración
Toda herramienta de desarrollo necesitará a veces (demasiado a menudo) solucionar problemas, y Docker Buildx no es una excepción. En esta sección, te guiaré a través de un par de problemas comunes para que puedas diagnosticarlos tú mismo rápidamente y volver a ponerte en marcha.
Problemas comunes y resoluciones
Al trabajar con Buildx, puedes encontrarte con un par de retos comunes. Aquí tienes los problemas más frecuentes y sus soluciones:
- Falla la creación del constructor. Si ves errores al crear un constructor con
docker buildx create
, comprueba tu versión de Docker:
docker version
Buildx requiere Docker 19.03 o posterior. Si utilizas una versión anterior, actualiza Docker para acceder a las funciones de Buildx.
Para los errores "no such plugin", asegúrate de que Buildx está correctamente instalado ejecutando:
docker buildx version
- Fallos de construcción multiplataforma. Cuando construyas para varias plataformas con errores como "error de formato de ejecución" o "manifiesto no coincidente", comprueba si QEMU está instalado:
docker buildx inspect --bootstrap
Si es necesario, instala emuladores de plataforma:
docker run --privileged --rm tonistiigi/binfmt --install all
- Problemas relacionados con la caché. Si tienes problemas con la caché, intenta borrar la caché de compilación local:
# Remove specific builder's cache
docker buildx prune -b mybuilder
# Remove all build cache
docker buildx prune --all
> ¿Qué es exactamente el comando Docker prune? Aprende con un montón de ejemplos prácticos.
- Problemas de conexión del demonio BuildKit. Si ves "no se ha podido resolver" o errores de conexión, reinicia el constructor:
docker buildx rm mybuilder
docker buildx create --name mybuilder --use
docker buildx inspect --bootstrap
- Cuestiones relacionadas con el rendimiento. Si las construcciones son lentas, prueba la salida de depuración para identificar los cuellos de botella:
docker buildx build --progress=plain --no-cache .
Esta salida detallada ayuda a identificar las fases de compilación que requieren más tiempo, permitiéndote optimizar tu archivo Docker en consecuencia.
- Fallos del comando "Cargar". Si te encuentras con el "error: docker exporter does not currently support exporting manifest lists" al utilizar
--load
con construcciones multiplataforma, recuerda que no se admite la carga simultánea de varias plataformas en el demonio Docker. En lugar de eso:
# Build for your current platform and load it
docker buildx build --platform linux/amd64 --load -t myapp:latest .
- Prácticas de depuración. Para problemas más complejos, estos métodos de depuración te ayudarán:
# Enable BuildKit debug logs
BUILDKIT_DEBUG=1 docker buildx build .
# Inspect the builder's internal state
docker buildx inspect
# Check system requirements
docker info
# For specific stage failures, build only up to that stage
docker buildx build --target problem-stage .
# Verify your Docker context
docker context ls
Si sigues sistemáticamente estos pasos para solucionar problemas, podrás resolver la mayoría de los problemas de Buildx y mantener un flujo de trabajo de construcción de contenedores eficiente.
Resumiendo la Guía Docker Buildx
¡Hemos cubierto mucho terreno en este artículo de Docker Buildx! Ya has visto cómo esta potente herramienta puede hacer que tus construcciones de contenedores sean más rápidas y flexibles.
Recuerda los beneficios clave: Puedes crear imágenes para múltiples plataformas con un solo comando, acelerar tus creaciones con un almacenamiento en caché avanzado y mantener tus imágenes seguras con una gestión secreta adecuada. Las mejoras de rendimiento son reales, especialmente cuando estructuras tus archivos Docker para aprovechar la construcción en paralelo.
Yo lo uso siempre en mi Macbook con chip M, ya que no todas las imágenes están disponibles para ARM.
Tanto si eres un programador en solitario como si formas parte de un gran equipo, Buildx te ofrece herramientas que se adaptan a tu flujo de trabajo. Puedes ejecutar compilaciones localmente, distribuirlas a través de contenedores, o incluso escalar a clusters Kubernetes a medida que crezcan tus necesidades.
Para saber más sobre Docker y Docker Buildx, te recomiendo que te inscribas en los siguientes cursos de DataCamp:
Domina Docker y Kubernetes
¡Aprende más sobre Docker con estos cursos!
Curso
Introduction to Docker
Curso
Intermediate Docker
blog
Los 13 mejores proyectos de AWS: De principiante a profesional

Tutorial
Cómo instalar y configurar MySQL en Docker
Tutorial
Cuentas de almacenamiento Azure: Tutorial paso a paso para principiantes

Anneleen Rummens
11 min
Tutorial
Base de datos Azure SQL: Configuración y gestión paso a paso

Anneleen Rummens
12 min
Tutorial
Cómo escribir un Bash Script: Un sencillo tutorial de Bash Scripting

Tutorial
Cómo utilizar Jupyter Notebooks: La guía definitiva

Adam Shafi
7 min