- Las imágenes multiarquitectura agrupan variantes AMD64 y ARM64 bajo una misma etiqueta mediante listas de manifests.
- Docker buildx y QEMU permiten construir imágenes multi-arch desde un único host para varias plataformas.
- Herramientas como docker manifest, ACR Tasks o ECR facilitan almacenar y gestionar estas imágenes en registros cloud.
- Integrar multi-arch en CI/CD (GitHub Actions, CodeBuild, etc.) simplifica soportar entornos mixtos y migraciones a ARM.

Si trabajas con contenedores y necesitas que tus aplicaciones funcionen tanto en servidores clásicos x86 como en dispositivos basados en ARM, tarde o temprano vas a tener que pelearte con las imágenes Docker multiarquitectura. La buena noticia es que hoy en día el ecosistema ha madurado muchísimo y crear, publicar y usar estas imágenes es bastante más sencillo de lo que parece a primera vista.
A lo largo de este artículo vamos a ver, con calma y en detalle, cómo crear imágenes multi-arch para AMD64 y ARM64, generar y publicar manifests y qué herramientas tienes a tu disposición (Docker buildx, docker manifest, GitHub Actions, ACR Tasks, AWS CodeBuild, etc.). Verás casos prácticos desde Linux, macOS con chip ARM, Raspberry Pi e incluso escenarios de CI/CD en la nube.
Contexto: por qué necesitas imágenes multiarquitectura
El primer punto clave es entender qué problema estamos resolviendo. Con Docker, empaquetamos aplicaciones y dependencias en contenedores portátiles y reproducibles. Eso funciona genial mientras toda tu infraestructura usa la misma arquitectura de CPU, normalmente AMD64 (x86-64). Pero hoy el panorama es bastante más variado.
Por un lado tenemos la arquitectura AMD64 (o x86-64), introducida por AMD como extensión de los procesadores x86 de 32 bits. Es la que domina en PCs de sobremesa, portátiles y muchos servidores: permite direcciones de 64 bits, mejora el rendimiento y sigue siendo compatible con el viejo software x86 de 32 bits. Vamos, el estándar de facto en la informática tradicional.
Por otro lado está ARM (AArch64 / ARM64), muy presente en móviles, tablets, sistemas embebidos y, de forma cada vez más agresiva, en servidores de centros de datos. Es una arquitectura RISC pensada para ser muy eficiente energéticamente, con chips más pequeños y mejor rendimiento por vatio, lo que la hace ideal para dispositivos de baja potencia y para abaratar el coste operativo en la nube.
En los últimos años han aparecido procesadores como AWS Graviton/Graviton2 y soluciones de Ampere, junto a la popularización de Raspberry Pi o los Mac con chip Apple Silicon (ARM64). Todo esto empuja a que queramos ejecutar la misma aplicación en entornos mixtos: equipos de desarrollo AMD64, clusters ARM en producción, entornos de test híbridos, etc.
Este cambio trae consigo un reto: si solo creas imágenes Docker AMD64, tus contenedores no corren de forma nativa en ARM (y viceversa). Podrías compilar manualmente en cada tipo de máquina, pero eso es un infierno de mantenimiento. Las imágenes multiarquitectura resuelven justo este embrollo.
Qué es una imagen Docker multiarquitectura (multi-arch)
Una imagen de arquitectura múltiple no es una “imagen mágica” que corre en todas partes sin más. En realidad es un conjunto de imágenes específicas por arquitectura (por ejemplo, una para AMD64 y otra para ARM64) que se agrupan bajo una misma etiqueta mediante una lista de manifests.
Cada imagen de contenedor está descrita por un manifest JSON. En ese manifest se indican la configuración de la imagen, sus capas, tamaños y el digest (un hash SHA256 inmutable que la identifica). Cuando quieres soportar varias arquitecturas, lo que haces es crear una lista de manifests (también llamada índice de imagen en el mundo OCI) que referencia varios manifests individuales, cada uno asociado a un sistema operativo y arquitectura concretos.
Por ejemplo, una lista de manifests puede agrupar una imagen Linux/amd64, otra Linux/arm64 e incluso alguna Windows/amd64. Para el usuario, todo se ve como una sola imagen con un tag (por ejemplo, miimagen:latest), pero internamente el registro mantiene ese índice con la lista de variantes.
La gracia está en que, cuando haces docker pull o docker run, el cliente de Docker negocia con el registro y selecciona automáticamente el manifest que coincide con la arquitectura y sistema operativo de la máquina donde se está ejecutando. No tienes que cambiar el tag ni acordarte de qué arquitectura estás usando: es el propio ecosistema el que elige por ti.
Esta misma idea la soportan Docker Hub, Azure Container Registry, Amazon ECR y muchos registros compatibles con la especificación de Docker Registry v2 y OCI. Es decir, la parte de almacenamiento está más que madura; lo que todavía evoluciona son las herramientas de construcción.
Plataformas soportadas y escenarios típicos

Docker permite construir imágenes para una buena colección de plataformas. Entre las más relevantes para contenedores Linux tenemos linux/amd64, linux/arm64, linux/arm/v7 (típico en Raspberry Pi), además de arquitecturas menos frecuentes como linux/riscv64, linux/ppc64le, linux/s390x o linux/386. También hay soporte para windows/amd64 y, de forma más marginal en contenedores, darwin/amd64.
En la práctica, la combinación más habitual hoy en día es linux/amd64 y linux/arm64. Es la que te va a permitir desplegar en servidores x86 convencionales y en máquinas ARM de nueva generación, tanto en la nube como on-premise.
Ejemplos de escenarios donde multi-arch tiene todo el sentido del mundo:
- Desarrollas en un Mac ARM64 pero despliegas en una instancia EC2 AMD64: quieres construir localmente una imagen que luego se ejecute en x86 sin montar un servidor de build extra.
- CI/CD en ARM, producción en x86: usas instancias Graviton2 baratas para compilar y testear, pero tu entorno productivo todavía está sobre AMD o Intel.
- Clusters Kubernetes híbridos: un EKS con grupos de nodos AMD64 y ARM64, donde un mismo Deploymente debe funcionar en ambas arquitecturas sin cambiar manifests de Kubernetes.
- Raspberry Pi en laboratorio y servidores x86 en producción, compartiendo la misma “meta-imagen” para asegurar comportamientos casi idénticos.
En todos estos casos, lo ideal es tener una única referencia de imagen (por ejemplo, miapp:1.0) que internamente resuelva la arquitectura adecuada.
Primeros pasos: preparar el entorno en Linux (Ubuntu)
Vamos a ver cómo configurar un equipo Linux (por ejemplo, Ubuntu 24.04) para crear imágenes tanto para ARM64 como para AMD64 usando un único host. Este tipo de configuración suele basarse en QEMU y binfmt-support, que permiten emular binarios de otras arquitecturas.
Partimos de que ya tienes Docker instalado y funcionando. Antes de nada, conviene actualizar el sistema:
sudo apt update
sudo apt upgrade
A continuación instalamos los componentes necesarios para buildx y la emulación multi-arch. En muchas distribuciones recientes, buildx viene ya integrado como plugin de Docker, pero en otras hay que instalar el paquete explícito junto con QEMU y binfmt:
sudo apt install docker-buildx qemu-system-arm qemu-user-static binfmt-support
Con esto, el kernel podrá registrar distintos formatos binarios y usar QEMU en modo usuario para ejecutar binarios de otras arquitecturas (por ejemplo, ARM64) desde un host AMD64, sin montar máquinas virtuales completas.
Podemos comprobar que buildx detecta las nuevas plataformas con:
sudo docker buildx inspect –bootstrap
El resultado debe mostrar una lista de plataformas entre las que aparecerán linux/amd64 y linux/arm64, junto a otras posibles. Si todavía no has creado ningún builder personalizado, este comando además inicializa uno basado en el driver docker-container.
Configurar un builder multiarquitectura con Docker buildx
Docker buildx es una extensión de la CLI de Docker que da acceso a las capacidades de BuildKit, el motor de construcción moderno. Entre sus ventajas están el soporte integrado de múltiples plataformas, la posibilidad de paralelizar builds y opciones útiles como –push o –output avanzadas.
Para trabajar cómodamente con varias arquitecturas vamos a crear un nuevo builder dedicado, usando el driver docker-container (que es el que soporta multiplataforma):
sudo docker buildx create –name multibuilder
sudo docker buildx use multibuilder
sudo docker buildx ls
Si quieres verificar la configuración con más detalle, puedes ejecutar:
sudo docker buildx inspect –bootstrap
La salida debe indicar algo similar a:
- Driver: docker-container
- Plataformas soportadas: linux/amd64, linux/arm64, linux/arm/v7, etc.
A partir de aquí, cualquier docker buildx build que lances utilizando este builder podrá apuntar a varias arquitecturas simultáneamente mediante el parámetro –platform.
Construir imágenes separadas para AMD64 y ARM64 en Ubuntu 24.04
Antes de meternos con la creación del manifest conjunto, es muy útil hacer una prueba básica construyendo una imagen sencilla para cada arquitectura por separado y verificando que funciona en cada tipo de máquina.
Imagina que tienes un Dockerfile muy simple para Ubuntu 24.04 que instala Apache y sirve una página “Hola Mundo”. Ese Dockerfile, junto con algún archivo HTML auxiliar, está en el directorio /mnt/storage/dockerfiles/ubuntu-24.04-apache-basic/.
Desde el host AMD64 (por ejemplo, un equipo con Ryzen o Intel), podrías construir y exportar las imágenes con:
sudo /usr/bin/docker buildx build –platform linux/amd64 \
/mnt/storage/dockerfiles/ubuntu-24.04-apache-basic/ \
-t ubuntu-24.04-apache-basic:latest \
–output type=docker,dest=/mnt/storage/dockerimages/ubuntu-24.04-apache-basic/$(date+»%Y%m%d-%H%M»).AMD64.tar
sudo /usr/bin/docker buildx build –platform linux/arm64 \
/mnt/storage/dockerfiles/ubuntu-24.04-apache-basic/ \
-t ubuntu-24.04-apache-basic:latest \
–output type=docker,dest=/mnt/storage/dockerimages/ubuntu-24.04-apache-basic/$(date+»%Y%m%d-%H%M»).ARM64.tar
Aquí estamos creando dos tarballs independientes, uno por arquitectura, usando –output type=docker para obtener un archivo que luego se puede cargar con docker load -i. Hay que hacerlo en dos pasos porque la salida tipo docker no soporta empaquetar varias arquitecturas en el mismo tar a la vez.
El parámetro –platform define las plataformas objetivo; y -t establece la etiqueta de la imagen. Una convención útil es incorporar la fecha y hora en formato YYYYmmdd-HHMM para versionar las builds.
Verificar las imágenes en máquinas AMD64 y ARM64

Para comprobar que todo funciona, puedes usar un equipo de escritorio AMD64 y una Raspberry Pi 4 (ARM64) como banco de pruebas, o cualquier otra combinación de máquinas.
En la máquina AMD64, primero confirmas la arquitectura con:
hostnamectl
La salida debe mostrar x86-64 como arquitectura del kernel. Después, cargas la imagen:
sudo docker load -i /mnt/storage/dockerimages/ubuntu-24.04-apache-basic/20251013-0244.AMD64.tar
Revisas que esté presente con:
docker images
Y la ejecutas mapeando el puerto 8080 al 80 del contenedor:
sudo docker run -d -p 8080:80 –name ubuntu-24.04-apache-basic ubuntu-24.04-apache-basic
Si accedes a http://127.0.0.1:8080 en el navegador, deberías ver el “Hola Mundo” servido por Apache desde la imagen AMD64.
En la máquina ARM64 (por ejemplo, una Raspberry Pi 4 con IP 10.0.0.190), haces un proceso similar. Compruebas el kernel con hostnamectl, cargas la imagen ARM64:
sudo docker load -i /mnt/storage/dockerimages/ubuntu-24.04-apache-basic/20251013-0244.ARM64.tar
Verificas con docker images y levantas el contenedor:
sudo docker run -d -p 8080:80 –name ubuntu-24.04-apache-basic ubuntu-24.04-apache-basic
A continuación, accedes vía navegador a http://10.0.0.190:8080 y confirmas que el Apache responde correctamente en ARM64. Con esto puedes dar por demostrado que tu Dockerfile es portable entre arquitecturas y que la construcción con buildx/QEMU funciona.
Limpiar entornos y buenas prácticas de housekeeping
Una vez terminadas las pruebas, no está de más dejar los entornos limpios para evitar que se acumulen contenedores e imágenes que ya no usas. En ambos equipos puedes parar y eliminar el contenedor, y luego borrar la imagen:
sudo docker container stop ubuntu-24.04-apache-basic
sudo docker container rm ubuntu-24.04-apache-basic
sudo docker image rm ubuntu-24.04-apache-basic
Además, si trabajas de forma intensiva con multi-arch, conviene automatizar limpiezas periódicas de imágenes obsoletas, builders temporales y capas intermedias para ahorrar espacio en disco, especialmente en entornos de CI/CD.
Crear y publicar una imagen multiarquitectura con docker manifest
El enfoque más clásico para multi-arch consiste en construir imágenes separadas para cada arquitectura, subirlas al registro (Docker Hub, ACR, ECR, etc.) y luego unirlas con docker manifest dentro de un único tag multi-arch.
La idea general es:
- Construyes y publicas myimage:amd64 y myimage:arm64 en tu registro.
- Creas una lista de manifests que combine ambas bajo un nuevo tag, por ejemplo myimage:multi o myimage:latest.
- Empujas ese manifest al registro.
- A partir de ahí, haces docker pull myimage:multi y Docker baja la variante que corresponde según la arquitectura del host.
Un ejemplo sencillo en Azure Container Registry sería:
docker tag myimage:arm64 \
myregistry.azurecr.io/multi-arch-samples/myimage:arm64
docker push myregistry.azurecr.io/multi-arch-samples/myimage:arm64
docker tag myimage:amd64 \
myregistry.azurecr.io/multi-arch-samples/myimage:amd64
docker push myregistry.azurecr.io/multi-arch-samples/myimage:amd64
Después creas la lista de manifests:
docker manifest create myregistry.azurecr.io/multi-arch-samples/myimage:multi \
myregistry.azurecr.io/multi-arch-samples/myimage:arm64 \
myregistry.azurecr.io/multi-arch-samples/myimage:amd64
Y finalmente la publicas:
docker manifest push myregistry.azurecr.io/multi-arch-samples/myimage:multi
Si ahora inspeccionas este tag con docker manifest inspect, verás una estructura JSON con varios manifests internos, cada uno con su digest, tamaño, arquitectura y sistema operativo. Lo mismo aplica si trabajas con Docker Hub o Amazon ECR.
Construcción multi-arch “todo en uno” con Docker buildx
El método anterior funciona bien y ayuda a entender qué es un manifest, pero resulta algo aparatoso. Ahí es donde Docker buildx brilla: te permite hacer una build multi-arch de forma directa, generando y empujando automáticamente el manifest al registro.
Por ejemplo, partiendo de un Dockerfile como este para Alpine:
FROM alpine
RUN apk add util-linux
CMD [«lscpu»]
Podrías lanzar una build multi-arch y subirla a Docker Hub con:
docker buildx build –platform linux/amd64,linux/arm64 \
-t foo4u/demo-mutliarch:2 \
–push .
Lo que hace buildx bajo el capó es:
- Transferir el contexto de build al contenedor builder.
- Construir una imagen por cada arquitectura listada en –platform.
- Subir todas las imágenes al registro con el tag indicado.
- Generar una lista de manifests que las referencie y publicarla bajo esa misma etiqueta.
Si luego ejecutas docker buildx imagetools inspect foo4u/demo-mutliarch:2, verás una salida indicando un manifest list con plataformas linux/amd64 y linux/arm64, cada una con su digest. Cuando hagas docker run en un host x86, verás que lscpu muestra x86_64, y en un host ARM mostrará aarch64.
Este flujo es mucho más fácil de automatizar en CI/CD, ya que basta un único comando buildx con –platform y –push para tenerlo todo listo en el registro.
Multi-arch con GitHub Actions y otros sistemas de CI
Cuando el equipo crece y quieres evitar builds manuales, lo lógico es integrar la construcción multi-arch en tu pipeline de CI/CD. Hoy en día, GitHub Actions, GitLab CI, Jenkins, CircleCI y compañía ofrecen runners con soporte para Docker y buildx, además de acciones específicas para configurar QEMU y multi-arch.
Un flujo típico con GitHub Actions sería:
- En el repositorio, creas un workflow que se ejecute en cada push a la rama principal.
- Usas una acción como docker/setup-buildx-action para instalar y configurar buildx y QEMU.
- Te logueas en Docker Hub u otro registro con credenciales almacenadas en GitHub Secrets.
- Lanzas un docker buildx build –platform linux/amd64,linux/arm64 –push con el tag de tu imagen.
El resultado es que sin consumir recursos locales tu repositorio genera imágenes listas para varias plataformas, siempre sincronizadas con el código de la rama principal. Para proyectos públicos, la capa gratuita de GitHub Actions suele ser suficiente; para privados, dispones de minutos incluidos y luego pago por uso.
ACR Tasks y listas de manifests en Azure Container Registry
Si trabajas en Azure, ACR Tasks ofrece una forma muy cómoda de crear e insertar imágenes multiarquitectura directamente en Azure Container Registry, usando definiciones YAML de varios pasos.
La estrategia suele ser parecida a la de docker manifest manual: por un lado, creas y subes imágenes específicas por arquitectura, y luego invocas docker manifest create y docker manifest push desde una tarea.
Un ejemplo de archivo YAML para ACR Tasks podría:
- Construir una imagen ARM64 desde dockerfile.arm64 y etiquetarla con un ID de ejecución.
- Construir una imagen AMD64 desde dockerfile.amd64, también con ese ID.
- Subir ambas al registro.
- Crear un manifest multi-arch etiquetado como latest combinando los dos tags anteriores.
- Empujar el manifest y opcionalmente inspeccionarlo al final.
Esto encaja muy bien con pipelines de Azure DevOps o GitHub Actions integrados con ACR, y delega en la propia plataforma de Azure la gestión de builds y publicación de manifests.
Imágenes multiarquitectura en AWS: CodeBuild, CodePipeline y Graviton2
En AWS, el patrón suele ser combinar CodePipeline y CodeBuild para orquestar builds sobre diferentes arquitecturas. AWS proporciona entornos de build basados tanto en Intel/AMD x86 como en ARM (Graviton2), y Amazon ECR entiende sin problemas las listas de manifests generadas con Docker.
Un diseño típico para soportar x86 y ARM en Amazon EKS sería:
- Un cluster EKS con dos node groups gestionados: uno AMD64 y otro ARM64, cada uno etiquetado con su arquitectura (kubernetes.io/arch).
- Una pipeline de AWS CodePipeline con tres etapas: Source (GitHub), Build (dos acciones en paralelo para x86 y ARM) y BuildManifest (crea la imagen multi-arch).
- En Build, dos proyectos de CodeBuild: uno corre en instancias x86 y genera la imagen para AMD64; otro corre en instancias ARM y genera la imagen para ARM64. Ambas se publican en Amazon ECR.
- En BuildManifest, un job combina ambas imágenes en un solo manifest multi-arch, subido también a ECR.
El cluster EKS utiliza a partir de ese momento un único URI de imagen (por ejemplo, 123456789012.dkr.ecr.region.amazonaws.com/miapp:multi) para desplegar en ambos tipos de nodo. Kubernetes, con ayuda de la información de arquitectura y el scheduler, se encarga de colocar cada Pod en el nodo adecuado para la imagen correspondiente.
Este enfoque aprovecha el mejor coste/rendimiento de Graviton2 en muchas cargas de trabajo, sin renunciar a la flexibilidad de volver a x86 si algo no va fino, simplemente reutilizando la parte AMD64 de la imagen multi-arch.
Trucos y consideraciones a la hora de crear imágenes multi-arch
Más allá de la teoría y de los ejemplos, hay varios detalles que conviene tener claros cuando diseñas imágenes para AMD64 y ARM64 de forma sistemática:
- Asegúrate de que la imagen base (FROM …) sea también multi-arch o tenga variantes separadas. Puedes comprobarlo con docker buildx imagetools inspect sobre la imagen base (por ejemplo, alpine, python:alpine3.10, amazoncorretto, etc.).
- Si tu lenguaje lo permite (Go, Java, .NET), favorece builds multiplataforma que generen binarios portables o bytecode que no dependa de la arquitectura, para que el mismo artefacto sirva para varias plataformas.
- Cuando uses herramientas nativas (C/C++, librerías con extensiones nativas, etc.), tendrás que asegurarte de que el proceso de compilación soporta cross-compiling o de que puedes compilar de forma nativa en cada arquitectura.
- Para escenarios locales en macOS o Windows, Docker Desktop ya viene con buildx y QEMU integrados, así que muchas veces no necesitas montar nada más para builds multi-arch.
- En Linux puro, si quieres instalar buildx “a mano”, puedes descargar el binario desde GitHub y colocarlo en ~/.docker/cli-plugins/docker-buildx, dándole permisos de ejecución. En ARM64, por ejemplo, puedes automatizarlo con un pequeño script que use la API de GitHub para localizar el último release y descargar el binario arm64.
Con todo esto en mente, montar un flujo robusto para crear imágenes multiarquitectura y publicar manifests para AMD64 y ARM64 deja de ser un experimento raro para convertirse en una práctica bastante estándar y, sobre todo, muy útil cuando trabajas con entornos híbridos, migraciones graduales a ARM o clusters Kubernetes con nodos heterogéneos.
Al final, la clave está en combinar bien las piezas: usar QEMU y buildx cuando quieres compilar desde un único host, apoyarte en herramientas como docker manifest o ACR Tasks cuando necesitas un control más granular, y escalar todo ello a CI/CD con GitHub Actions, CodeBuild o pipelines similares para mantener tus imágenes multi-arch siempre actualizadas y listas para correr en cualquier arquitectura sin que el equipo tenga que romperse la cabeza en cada despliegue.
Redactor apasionado del mundo de los bytes y la tecnología en general. Me encanta compartir mis conocimientos a través de la escritura, y eso es lo que haré en este blog, mostrarte todo lo más interesante sobre gadgets, software, hardware, tendencias tecnológicas, y más. Mi objetivo es ayudarte a navegar por el mundo digital de forma sencilla y entretenida.
