Cómo generar imágenes de Docker compatibles con Apple M1 desde GitHub Actions

Desde que renové mi Macbook Pro he tenido algunos «problemillas» con algunas imágenes de Docker, debido a que la arquitectura para la que se generaron estas no es compatible con la que espera este nuevo chip, ARM. Si tú también tienes un M1 habrás podido comprobar que imágenes de Docker que hacen uso de .NET Core de repente dan errores como el siguiente:

Unhandled exception. System.IO.IOException: Function not implemented

En este artículo quiero compartir contigo el flujo que utilizo de GitHub Actions para generar mis imágenes en múltiples plataformas, incluida linux/arm64, que es la que necesita este chip.

El flujo

Para poder generar imágenes con diferentes arquitecturas he cambiado el flujo que tenía de GitHub Actions de este:

name: GitHub Packages demo
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
jobs:
  build:   
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Login GitHub Packages
        uses: docker/login-action@v1
        with:
          registry: docker.pkg.github.com
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Short the sha to 7 characters only
        id: vars
        run: echo ::set-output name=tag::$(echo ${GITHUB_SHA::7})
      - uses: docker/build-push-action@v2
        with:         
          context: .         
          push: true
          tags: docker.pkg.github.com/0gis0/tour-of-heroes-dotnet-api/tour-of-heroes-api:${{ steps.vars.outputs.tag }}

A este:

name: GitHub Packages demo
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
jobs:
  build:   
    runs-on: ubuntu-latest
    steps:
    
      - uses: actions/checkout@v3
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
        
      - name: Login GitHub Packages
        uses: docker/login-action@v2
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Short the sha to 7 characters only
        id: vars
        run: echo ::set-output name=tag::$(echo ${GITHUB_SHA::7})
      - uses: docker/build-push-action@v3
        with:         
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ghcr.io/0gis0/tour-of-heroes-dotnet-api/tour-of-heroes-api:${{ steps.vars.outputs.tag }}

Como puedes ver, he actualizado las versiones de algunas de las acciones que se habían quedado obsoletas, he añadido las acciones Set up QEMU y Setup Docker Buildx y por último he modificado la última de ellas, donde utilizo build-push-action@v3, para especificar para qué arquitecturas quiero que se genere la imagen. En mi caso para linux/amd64, para que me siga funcionando en el resto de sistemas que tengo, y linux/arm64, que es la que necesito para Apple M1.

¡Saludos!