- Las imágenes Docker multiarquitectura se basan en listas de manifiestos que agrupan variantes para AMD64, ARM64 y otros sistemas.
- QEMU y Docker Buildx permiten compilar desde un solo host Linux imágenes multiplataforma listas para usar en distintos entornos.
- Con docker manifest y Buildx se pueden combinar y publicar fácilmente las variantes en un único tag accesible desde cualquier arquitectura.
- Integrar multi-arch en CI/CD simplifica despliegues en clusters heterogéneos y facilita migrar a servidores ARM sin cambiar tags.

Crear imágenes Docker que funcionen igual de bien en AMD64 y ARM64 ya no es un capricho de frikis, es casi una necesidad si trabajas con Mac Apple Silicon, Raspberry Pi, Graviton en AWS o servidores ARM en cloud. El problema típico: compilas en tu máquina, subes la imagen, y al ejecutarla en otra arquitectura explota porque los binarios no coinciden con la CPU.
La buena noticia es que Docker, Buildx, QEMU y los manifiestos multi-arch nos permiten generar “meta-imágenes” que se adaptan solas a la arquitectura del host. Tú haces un docker pull con una única etiqueta y el motor se encarga de descargar la variante correcta para AMD64, ARM64, Windows o Linux sin que tengas que pelearte con tags raros.
Qué es Docker y por qué importa la arquitectura

Docker es una plataforma de contenedores que empaqueta una aplicación y todas sus dependencias en una unidad autocontenida, ligera y aislada. Esas unidades se llaman imágenes, y cuando las ejecutas obtienes contenedores. La clave es que la imagen incluye todo lo necesario para funcionar: sistema base, librerías, binarios, configuración…
Al usar contenedores eliminarás muchos problemas de “en mi máquina funciona”, porque el entorno es reproducible en cualquier host con Docker compatible. Sin embargo, hay una limitación importante: el host debe poder ejecutar los binarios que van dentro de la imagen, y ahí entra en juego la arquitectura de CPU y el sistema operativo.
Cuando hablamos de arquitectura con Docker no nos referimos solo a AMD64 vs ARM64, también al sistema operativo: Linux, Windows, diferentes versiones de kernel, etc. Un host Linux x86-64 no puede ejecutar directamente una imagen con binarios Windows, y un host ARM64 no puede ejecutar binarios compilados solo para x86-64 sin emulación.
AMD64, ARM64 y el auge de ARM en datacenters
AMD64 (o x86-64) es la evolución de la vieja arquitectura x86 de 32 bits, diseñada originalmente por AMD y adoptada por prácticamente todos los fabricantes. Es la arquitectura estándar en la mayoría de PCs de sobremesa, portátiles y muchos servidores actuales. Ofrece soporte de 64 bits, mayor espacio de direcciones y mejor rendimiento frente a x86 de 32 bits, manteniendo compatibilidad hacia atrás con el software anterior.
Por otro lado, ARM64 (también conocida como AArch64) es una arquitectura RISC usada históricamente en móviles, sistemas embebidos y dispositivos de bajo consumo. Sus procesadores están muy orientados a la eficiencia energética, con diseños más simples que ejecutan muchas operaciones pequeñas de forma muy rápida, usando menos energía y menos espacio físico en placa.
En los últimos años ARM ha dado el salto al mundo de los datacenters. Fabricantes como AWS (con sus CPUs Graviton), Ampere o incluso Apple con sus chips M1/M2 han demostrado que ARM puede ofrecer un rendimiento por vatio muy atractivo frente a x86-64 para muchas cargas de trabajo modernas.
Las principales razones por las que ARM se está metiendo de lleno en los centros de datos son varias: mejor eficiencia energética (menos gasto de electricidad y refrigeración), mayor densidad de servidores en el mismo rack, chips más baratos de fabricar y diseños optimizados para cargas de trabajo como IA, bases de datos y microservicios. Todo esto hace que muchas empresas quieran poder desplegar los mismos contenedores tanto en x86-64 como en ARM64 sin dolores de cabeza.
Imágenes multi-arquitectura: qué son realmente
Cuando oyes hablar de imágenes Docker multiarquitectura o multiplataforma puede dar la sensación de que existe una sola imagen mágica capaz de ejecutarse en cualquier CPU u OS. En realidad, técnicamente lo que hay son varias imágenes “normales”, cada una construida para una plataforma distinta, y un manifest list o índice que las agrupa bajo una misma etiqueta.
Cada imagen individual se describe con un manifiesto de imagen. Es un JSON que indica el digest (hash SHA256) de la configuración de la imagen, las capas que la componen, sus tamaños y metadatos. Algo así como la ficha técnica de esa imagen concreta. En Docker y en registros como Azure Container Registry puedes inspeccionar estos manifiestos para ver sus detalles.
Por encima de eso existe la lista de manifiestos (manifest list o índice de imagen OCI). Esta lista agrupa varios manifiestos individuales, uno por arquitectura / sistema operativo, incluyendo los campos de plataforma: CPU (amd64, arm64, 386, ppc64le, s390x, etc.), sistema operativo (linux, windows) y detalles adicionales como la versión de Windows.
Cuando haces un docker pull miimagen:tag donde ese tag apunta en realidad a una lista de manifiestos, el cliente Docker detecta esa estructura, mira su propia arquitectura y sistema operativo, y descarga solo el manifiesto y las capas correspondientes a su plataforma. Para el usuario, parece una sola imagen; internamente, es un manifiesto que referencia a varios artefactos independientes.
Manifiestos, listas de manifiestos y cómo gestionarlos
En el día a día, la herramienta principal para tratar con manifiestos multi-arch es el comando docker manifest de la CLI. Este comando es experimental, por lo que en algunas configuraciones de Docker hay que activar las funcionalidades experimentales en la configuración del cliente (fichero ~/.docker/config.json con "experimental": "enabled").
Un manifiesto de imagen estándar contiene campos como schemaVersion, mediaType, config y la lista de layers. La lista de manifiestos (para multi-arch) es otro JSON con mediaType específico de listas y un array manifests donde cada entrada indica la arquitectura, sistema operativo, digest de la imagen concreta y tamaño. Con docker manifest inspect puedes ver exactamente qué combinaciones soporta una etiqueta determinada.
Registros como Azure Container Registry o Docker Hub entienden de forma nativa estas listas de manifiestos. En Azure, por ejemplo, puedes ver la información de manifiestos con la CLI (az acr manifest list-metadata) o desde el portal. Para importar una imagen multi-arch existente a ACR basta con usar az acr import igual que con una imagen simple: ACR conservará la estructura multi-arch sin que tengas que hacer nada especial.
Además de la CLI de Docker, Azure ACR Tasks y otros sistemas de CI/CD permiten definir flujos multi-paso en YAML donde se construyen imágenes específicas por arquitectura, se suben al registro y luego se crea y publica el manifiesto unificado. Esto encaja muy bien con pipelines que ya generan artefactos AMD64 y ARM64 por separado.
Por qué te interesa usar imágenes multiarquitectura
Más allá de la teoría, las ventajas prácticas de las imágenes multi-arch son bastante claras cuando trabajas en equipos mixtos o en infraestructuras híbridas:
- Mismo tag para todos: desarrolladores en Mac ARM, Linux x86-64, Raspberry Pi o servidores ARM pueden hacer
docker pull miapp:latesty cada uno obtendrá la variante que le toca, sin tener que recordar sufijos ni tags por arquitectura. - Compatibilidad con clusters heterogéneos: en Kubernetes o Docker Swarm puedes tener nodos AMD64 y ARM64 y compartir imágenes base para microservicios, herramientas, sidecars, etc.
- Migraciones progresivas: es fácil probar en paralelo ARM y x86-64. Puedes ejecutar entornos de test en ARM (por coste) y producción en x86-64, o al revés, y conmutar sin tener que cambiar referencias de imagen.
- Ahorro en CI/CD y cloud: si montas tu servidor de compilación en ARM (por ejemplo, una instancia Graviton) puedes construir imágenes multi-arch para ambas plataformas desde un único host con QEMU y Buildx, ahorrando dinero frente a usar solo máquinas x86-64.
Dos estrategias: manifest clásico vs Docker Buildx
Hoy en día tienes dos formas principales de conseguir una imagen multi-arch compatible con AMD64 y ARM64 (y más arquitecturas si quieres):
La primera es el enfoque “clásico”, usando docker manifest create. Con este método construyes una imagen por arquitectura, cada una con su propia etiqueta (por ejemplo miimagen:amd64 y miimagen:arm64), las subes al registro, y después creas un manifiesto que las agrupa bajo un tag “virtual” (por ejemplo miimagen:multi o miimagen:latest). Finalmente empujas ese manifiesto al registro con docker manifest push.
La segunda estrategia consiste en usar Docker Buildx, un plugin de la CLI que delega las compilaciones en BuildKit y añade soporte nativo para builds multiplataforma. Con Buildx puedes construir y publicar en un solo comando todas las variantes y el manifiesto, sin crear y empujar imágenes por separado manualmente. Además de --platform, Buildx incorpora flags como --push para enviar directamente al registro y --output para controlar el destino (tar, local, etc.).
Elegir un enfoque u otro depende de tu contexto: Docker Manifest es muy transparente y fácil de acoplar a infra que ya tienes, sobre todo si compilas nativamente en cada arquitectura. Buildx, en cambio, brilla cuando quieres centralizar la compilación en un solo host y montar pipelines automatizados de múltiples targets desde un mismo punto.
Preparar Ubuntu 24.04 para construir imágenes AMD64 y ARM64
Si trabajas sobre Linux, por ejemplo un Ubuntu 24.04 en un equipo x86-64 (AMD Ryzen o Intel), puedes montar un entorno capaz de generar imágenes para ambas arquitecturas utilizando QEMU y Buildx. Se parte de la premisa de que Docker ya está instalado y funcionando correctamente.
Lo primero es asegurarse de que el sistema está al día:
sudo apt update
sudo apt upgrade
A continuación instalas los componentes necesarios para la compilación multiplataforma: docker-buildx, QEMU y soporte para formatos binarios múltiples:
sudo apt install docker-buildx qemu-system-arm qemu-user-static binfmt-support
Con esto, el kernel podrá usar QEMU en modo usuario para emular llamadas de sistema de ARM64 en una máquina AMD64. Luego conviene comprobar que Docker reconoce las arquitecturas extra a través de Buildx:
sudo docker buildx inspect --bootstrap
El siguiente paso es crear un builder específico multi-plataforma y activarlo:
sudo docker buildx create --name multibuilder
sudo docker buildx use multibuilder
sudo docker buildx ls
En la salida verás un nodo con un driver docker-container y una lista de plataformas soportadas, entre ellas linux/amd64 y linux/arm64. A partir de aquí ya puedes construir imágenes targeting ambas arquitecturas desde esta misma máquina.
Ejemplo práctico: imagen Ubuntu 24.04 con Apache para AMD64 y ARM64
Para comprobar que todo funciona, es habitual preparar un Dockerfile sencillo basado en Ubuntu 24.04 que instale Apache y sirva una página HTML con un “Hola Mundo”. Supongamos que tienes los archivos en /mnt/storage/dockerfiles/ubuntu-24.04-apache-basic/ y quieres generar imágenes separadas para AMD64 y ARM64.
Con Buildx puedes lanzar dos builds, una por plataforma, exportando cada resultado como un archivo .tar para cargarlo después en otras máquinas:
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
No se está creando un manifest multi-arch todavía, sino dos imágenes independientes, una por arquitectura. Esto viene bien para verificar que cada variante se ejecuta correctamente en su plataforma nativa antes de agruparlas.
Verificar la imagen en AMD64 y en ARM64
En una máquina de escritorio con Linux x86-64 (por ejemplo un Ryzen o Intel), puedes cargar la imagen AMD64 y probar el contenedor. Primero compruebas la arquitectura del host con hostnamectl (verás x86-64 o similar), y luego:
sudo docker load -i /mnt/storage/dockerimages/ubuntu-24.04-apache-basic/20251013-0244.AMD64.tar
Con docker images verificas que la imagen está disponible, y a continuación levantas el contenedor:
sudo docker run -d -p 8080:80 --name ubuntu-24.04-apache-basic ubuntu-24.04-apache-basic
Si abres el navegador en http://127.0.0.1:8080 deberías ver la página de “Hola Mundo” servida por Apache. En una Raspberry Pi 4 (ARM64) el proceso es similar: miras la arquitectura con hostnamectl, cargas el .tar para ARM64 y ejecutas el contenedor en el puerto 8080. Al acceder a la IP de la Pi (por ejemplo http://10.0.0.190:8080) comprobarás que la variante ARM también funciona.
Una vez terminadas las pruebas, es buena idea limpiar contenedores e imágenes en ambos equipos con:
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
Crear y publicar un manifest multi-arch a mano
Si ya tienes construidas y subidas todas las variantes (por ejemplo miimagen:arm64 y miimagen:amd64 en Docker Hub o en ACR), el siguiente paso es combinar las imágenes en un único manifest multi-arch. Para ello se usa docker manifest create indicando la “meta etiqueta” y las imágenes que formarán parte de ella.
Un ejemplo típico para Azure Container Registry con dos arquitecturas Linux 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
Y después se crea la lista de manifiestos:
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
Por último empujas el manifiesto al registro con:
docker manifest push myregistry.azurecr.io/multi-arch-samples/myimage:multi
A partir de ahí, cualquier docker pull sobre myregistry.azurecr.io/multi-arch-samples/myimage:multi devolverá la variante adecuada para la plataforma desde la que se haga la petición, sin que el usuario tenga que preocuparse de si el host es AMD64 o ARM64.
Automatizar manifest y multi-arch en CI/CD
Integrar este proceso en un pipeline de CI/CD evita tener que teclear comandos a mano cada vez que subes una nueva versión. En entornos como Azure DevOps puedes definir jobs separados para construir y subir la imagen Linux y la Windows, o la AMD64 y la ARM64, y luego un job final que cree y publique el manifiesto multi-arch.
En estos escenarios suele usarse la tarea de Docker integrada para hacer login seguro en el registro (Docker Hub, ACR, etc.), dejando que la pipeline gestione credenciales a través de conexiones de servicio. Después un script Bash puede copiar el fichero de configuración que genera la tarea de Docker, habilitar el modo experimental y ejecutar docker manifest create y docker manifest push para los tags que te interesen (por ejemplo dev y latest).
La clave está en que el job que crea el manifiesto dependa de los jobs que construyen y empujan las imágenes. Así te aseguras de que el manifest siempre apunte a los digests correctos. Recuerda que si vuelves a compilar una de las variantes, su hash SHA256 cambiará y el manifiesto tendría que recrearse para no quedar desfasado.
Buildx: compilaciones multiplataforma en un solo comando
Docker Buildx va un paso más allá del enfoque clásico porque integra la compilación multi-arch directamente en el proceso de build. En lugar de crear imágenes separadas y luego combinar, puedes generar y publicar, de una tacada, todas las arquitecturas que necesites, junto al manifest list correspondiente.
Para usar Buildx necesitas Docker 19.03 o superior y un kernel moderno (en Linux, 5.x o posterior). En muchas distros actuales, Buildx ya viene en forma de plugin (docker-buildx-plugin) y solo hay que asegurarse de instalarlo. En otras, se puede descargar el binario desde GitHub e instalarlo en ~/.docker/cli-plugins/docker-buildx, marcándolo como ejecutable.
Una vez instalado, creas un builder y lo habilitas:
docker buildx create --name mbuilder
docker buildx use mbuilder
docker buildx inspect --bootstrap
En la salida verás que el driver es docker-container y una lista de plataformas que incluye linux/arm64, linux/amd64 y muchas más (riscv64, ppc64le, s390x, arm v7 y v6…). Eso significa que tu builder está preparado para crear imágenes para todas esas arquitecturas usando QEMU en modo usuario si hace falta.
El siguiente paso sería tomar un Dockerfile sencillo, por ejemplo:
FROM alpine
RUN apk add util-linux
CMD ["lscpu"]
Y lanzar una build multi-arch directamente al registro con:
docker buildx build --platform linux/amd64,linux/arm64 -t usuario/demo-multiarch:2 --push .
Con este comando el builder construye en paralelo las imágenes para AMD64 y ARM64, resuelve la imagen base multi-arch (alpine) en cada plataforma, genera el manifest list y lo sube todo al registro. Después puedes inspeccionar el resultado con docker buildx imagetools inspect usuario/demo-multiarch:2 y verás una estructura JSON con dos manifiestos, uno por arquitectura.
Uso real: ejecutar la misma imagen en AMD64 y ARM64
Una vez que tienes publicada una imagen multi-arch, el consumo no cambia respecto a una imagen normal: simplemente haces docker run usuario/demo-multiarch:2 en cualquier host y Docker se preocupa de traer lo que corresponde. En una máquina AMD64, el contenedor terminará reportando Architecture: x86_64 al ejecutar lscpu; en una máquina ARM64 aparecerá aarch64.
Este patrón es especialmente cómodo si desarrollas en una Mac con chip M1/M2 pero despliegas en servidores EC2 AMD64, o si tienes una mezcla de Raspberry Pi y nodos x86-64 en tu infraestructura. En lugar de compilar manualmente en el servidor objetivo o mantener repositorios paralelos de imágenes, centralizas la build y publicas una sola referencia.
Para lenguajes con buen soporte multi-arch (como Go o Java) puedes incluso compilar el binario una única vez para la plataforma de build usando --platform=$BUILDPLATFORM en el FROM de tu Dockerfile y dejar que la parte runtime se base en una imagen multi-arch (por ejemplo amazoncorretto:11). De esta forma, el mismo jar o binario sube a varias imágenes finales para distintas arquitecturas.
Con todo esto sobre la mesa, tener un pipeline y un flujo de trabajo claro para construir imágenes Docker multiarquitectura y publicar su manifest para AMD64 y ARM64 te permite moverte con soltura entre entornos de desarrollo heterogéneos, aprovechar mejor las CPU ARM en cloud y simplificar la gestión de tags y despliegues, reduciendo al mínimo los típicos problemas de compatibilidad entre máquinas diferentes.
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.

