Compartir comentarios
Las respuestas se generan en base a la documentación.

Imágenes multiplataforma con GitHub Actions

Puedes compilar imágenes multiplataforma utilizando la opción platforms, como se muestra en el siguiente ejemplo:

Note
  • Para obtener una lista de las plataformas disponibles, consulta la acción Docker Setup Buildx.
  • Si deseas compatibilidad con más plataformas, puedes usar QEMU con la acción Docker Setup QEMU.
name: ci

on:
  push:

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Iniciar sesión en Docker Hub
        uses: docker/login-action@v4
        with:
          username: ${{ vars.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Configurar QEMU
        uses: docker/setup-qemu-action@v4

      - name: Configurar Docker Buildx
        uses: docker/setup-buildx-action@v4

      - name: Compilar y enviar
        uses: docker/build-push-action@v7
        with:
          platforms: linux/amd64,linux/arm64
          push: true
          tags: user/app:latest

Compilar y cargar imágenes multiplataforma

La configuración predeterminada de Docker para los runners de GitHub Actions admite la compilación y el envío de imágenes multiplataforma a los registros. Sin embargo, no admite la carga de imágenes multiplataforma en el almacenamiento de imágenes local del runner después de compilarlas. Para cargar una imagen multiplataforma localmente, debes habilitar la opción del almacén de imágenes de containerd para el Docker Engine.

No hay forma de configurar la instalación predeterminada de Docker en los runners de GitHub Actions directamente, pero puedes usar docker/setup-docker-action para personalizar la configuración del Docker Engine y de la CLI para un trabajo (job).

El siguiente flujo de trabajo de ejemplo habilita el almacén de imágenes de containerd, compila una imagen multiplataforma y carga los resultados en el almacén de imágenes local del runner de GitHub.

name: ci

on:
  push:

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Configurar Docker
        uses: docker/setup-docker-action@v5
        with:
          daemon-config: |
            {
              "debug": true,
              "features": {
                "containerd-snapshotter": true
              }
            }

      - name: Iniciar sesión en Docker Hub
        uses: docker/login-action@v4
        with:
          username: ${{ vars.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Configurar QEMU
        uses: docker/setup-qemu-action@v4

      - name: Compilar y enviar
        uses: docker/build-push-action@v7
        with:
          platforms: linux/amd64,linux/arm64
          load: true
          tags: user/app:latest

Distribuir la compilación en múltiples runners

Compilar para múltiples plataformas en el mismo runner puede aumentar significativamente los tiempos de compilación, particularmente cuando se trata de Dockerfiles complejos o de una gran cantidad de plataformas de destino. Si deseas dividir las compilaciones de plataformas en múltiples runners sin tener que mantener una matriz personalizada y un trabajo de fusión (merge job), utiliza el Docker GitHub Builder. Los flujos de trabajo reutilizables calculan la matriz por plataforma, ejecutan cada plataforma en su propio runner y crean el manifiesto final por ti.

El siguiente flujo de trabajo utiliza el flujo de trabajo reutilizable build.yml para distribuir una compilación de Dockerfile multiplataforma:

name: ci

on:
  push:

permissions:
  contents: read

jobs:
  build:
    uses: docker/github-builder/.github/workflows/build.yml@v1
    permissions:
      contents: read
      id-token: write
    with:
      output: image
      push: true
      platforms: linux/amd64,linux/arm64
      meta-images: user/app
      meta-tags: |
        type=ref,event=branch
        type=ref,event=pr
        type=semver,pattern={{version}}
        type=semver,pattern={{major}}.{{minor}}
    secrets:
      registry-auths: |
        - registry: docker.io
          username: ${{ vars.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

Con distribute: true, que es el valor predeterminado, el flujo de trabajo divide la compilación en una plataforma por runner y ensambla la imagen multiplataforma final en su fase de finalización (finalize phase). El mapeo predeterminado de runner envía las plataformas Linux Arm a ubuntu-24.04-arm y utiliza ubuntu-24.04 para otras plataformas. Para personalizar el mapeo, consulta la selección de runners (runner selection). Si necesitas controlar las entradas de compilación de Docker directamente, consulta Compilar con la acción Docker GitHub Builder build.yml.

Con Bake

Puedes utilizar el flujo de trabajo reutilizable bake.yml para el mismo patrón cuando tu compilación esté definida en un archivo Bake. El flujo de trabajo lee las plataformas de destino de la definición de Bake, distribuye las compilaciones por plataforma y publica el manifiesto final sin necesidad de un trabajo de preparación o de fusión separado.

variable "DEFAULT_TAG" {
  default = "app:local"
}

// Target especial: https://github.com/docker/metadata-action#bake-definition
target "docker-metadata-action" {
  tags = ["${DEFAULT_TAG}"]
}

// Target predeterminado si no se especifica ninguno
group "default" {
  targets = ["image-local"]
}

target "image" {
  inherits = ["docker-metadata-action"]
}

target "image-local" {
  inherits = ["image"]
  output = ["type=docker"]
}

target "image-all" {
  inherits = ["image"]
  platforms = [
    "linux/amd64",
    "linux/arm/v6",
    "linux/arm/v7",
    "linux/arm64"
  ]
}
name: ci

on:
  push:

permissions:
  contents: read

jobs:
  bake:
    uses: docker/github-builder/.github/workflows/bake.yml@v1
    permissions:
      contents: read
      id-token: write
    with:
      output: image
      push: true
      target: image-all
      meta-images: user/app
      meta-tags: |
        type=ref,event=branch
        type=sha
    secrets:
      registry-auths: |
        - registry: docker.io
          username: ${{ vars.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}