Arquitectura de Docker GitHub Builder
Docker GitHub Builder separa la orquestación del repositorio de la implementación de la compilación.
Un repositorio de consumo decide cuándo se ejecuta una compilación, qué permisos y secretos se conceden,
y qué entradas se pasan. El flujo de trabajo reutilizable en el repositorio docker/github-builder
es el propietario de la implementación de la compilación en sí. Esa división mantiene los flujos de trabajo
de los repositorios cortos a la vez que centraliza BuildKit, el almacenamiento en caché, la procedencia,
la generación de SBOM, la firma y el ensamblaje multiplataforma en una única ruta mantenida por Docker.

Arquitectura principal
Un flujo de trabajo emisor invoca build.yml o bake.yml.
build.yml es el punto de entrada para compilaciones orientadas a Dockerfile.
bake.yml es el punto de entrada para compilaciones orientadas a Bake, donde la definición de Bake
sigue siendo la fuente de verdad para los targets y las anulaciones. En ambos casos, el emisor sigue siendo
el propietario de las políticas del repositorio, incluidos los desencadenadores, las condiciones de las ramas,
los permisos, los secretos, la selección de targets, las entradas de metadatos y la elección entre la salida
de imagen y la salida local.
Dentro del flujo de trabajo reutilizable, la primera fase prepara la compilación. Valida las entradas
entrantes, resuelve la configuración del runner y expande una solicitud multiplataforma en un trabajo
por plataforma. El modelo de ejecución se puede visualizar como una matriz donde linux/amd64 se ejecuta
en ubuntu-24.04 y linux/arm64 se ejecuta en ubuntu-24.04-arm. Cada trabajo de plataforma se compila
de forma independiente, y luego el flujo de trabajo finaliza el resultado en un único contrato de salida
de cara al emisor.
plataformas solicitadas: linux/amd64,linux/arm64
trabajos de plataforma conceptuales: linux/amd64 -> ubuntu-24.04
linux/arm64 -> ubuntu-24.04-armSelección de runners
La entrada runner acepta una única etiqueta de runner de Linux alojado en GitHub o una asignación
de plataformas delimitada por saltos de línea.
El valor predeterminado es una asignación de plataformas que utiliza runners de Ubuntu alojados en GitHub:
runner: |
default=ubuntu-24.04
linux/arm=ubuntu-24.04-arm
linux/arm64=ubuntu-24.04-armEn el trabajo de plataforma, la etiqueta del runner se resuelve en un único valor:
runner: ubuntu-24.04Una asignación debe definir un runner default. Las otras claves son prefijos de plataforma, y el
prefijo coincidente más específico tiene prioridad. Por ejemplo, linux/arm coincide con variantes
como linux/arm/v7, mientras que linux/arm64 es un prefijo independiente.
En el siguiente ejemplo, linux coincide con plataformas Linux que no coinciden con un prefijo
más largo. La clave default sigue siendo requerida porque es la opción de respaldo cuando ningún
prefijo de plataforma coincide.
runner: |
default=ubuntu-24.04
linux=ubuntu-24.04
linux/arm=ubuntu-24.04-arm
linux/arm64=ubuntu-24.04-armLos flujos de trabajo reutilizables requieren runners de Linux alojados en GitHub. Los valores
heredados auto, amd64 y arm64 se siguen aceptando por compatibilidad, pero emiten advertencias
de obsolescencia. Utiliza en su lugar una etiqueta de runner explícita o una asignación de plataformas.
Ruta de ejecución

La ruta de ejecución se mantiene corta a propósito. El repositorio de consumo llama al flujo de trabajo reutilizable. El flujo de trabajo reutilizable prepara la compilación, ejecuta los trabajos por plataforma y finaliza el resultado. Para la salida de imágenes, la finalización produce una imagen de registro y un manifiesto multiplataforma. Para la salida local, la finalización fusiona los archivos de cada plataforma y puede subir el resultado fusionado como un artefacto de GitHub. El emisor no necesita reconstruir cómo se conectaron Buildx, BuildKit, el almacenamiento en caché o el ensamblaje del manifiesto.
Los dos puntos de entrada reutilizables
build.yml se adapta mejor cuando la compilación ya está expresada como un flujo de
trabajo orientado a Dockerfile. Se alinea de forma natural con conceptos como context, file, target,
build-args, labels, annotations y platforms. Este es el punto de entrada que se siente más
cercano a docker/build-push-action, excepto que la implementación del flujo de trabajo está centralizada.
bake.yml se adapta mejor cuando el repositorio ya utiliza Bake como definición de compilación.
Preserva el modelo de Bake, incluida la resolución de targets, files, set y vars, al tiempo que
enruta la ejecución a través de la misma ruta de compilación mantenida por Docker. Un detalle arquitectónico
importante es que el flujo de trabajo de Bake se centra en un target por llamada de flujo de trabajo, lo que
mantiene la procedencia, el manejo de resúmenes (digests) y el ensamblaje final del manifiesto limitados a
una unidad de compilación a la vez.
Modelo de salida
Los flujos de trabajo reutilizables exponen un conjunto estable de salidas de cara al emisor para que
los trabajos posteriores puedan consumir los resultados sin comprender el gráfico de trabajos internos.
En la práctica, los valores principales son digest, meta-json, artifact-name, output-type y
signed. Ese contrato es importante porque mantiene la promoción, publicación o automatización
posterior desacoplada de la mecánica de selección de runners y el ensamblaje por plataforma.
Ejemplos
Compilación de imagen orientada a Dockerfile
El siguiente ejemplo muestra la forma de una compilación de imagen multiplataforma impulsada
por build.yml.
name: ci
on:
push:
branches:
- "main"
tags:
- "v*"
pull_request:
permissions:
contents: read
jobs:
build:
uses: docker/github-builder/.github/workflows/build.yml@v1
permissions:
contents: read
id-token: write
with:
output: image
push: ${{ github.event_name != 'pull_request' }}
platforms: linux/amd64,linux/arm64
meta-images: name/app
meta-tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
secrets:
registry-auths: |
- registry: docker.io
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}Esta llamada es pequeña porque el flujo de trabajo reutilizable se encarga del trabajo pesado. El repositorio decide cuándo debe ejecutarse la compilación y qué entradas desea, mientras que la implementación compartida maneja la configuración de Buildx, la configuración de BuildKit, la distribución por plataformas (platform fan-out), la generación de metadatos, la procedencia, la generación de SBOM, la firma y la creación del manifiesto final.
Salida local orientada a Bake
El siguiente ejemplo muestra la forma de una llamada de Bake que exporta salida local y sube el artefacto fusionado.
name: ci
on:
pull_request:
permissions:
contents: read
jobs:
bake:
uses: docker/github-builder/.github/workflows/bake.yml@v1
permissions:
contents: read
id-token: write
with:
output: local
target: binaries
artifact-upload: true
artifact-name: bake-outputEsta forma es útil cuando el repositorio ya mantiene su definición de compilación en Bake y desea preservar esa fuente de verdad. El flujo de trabajo inyecta el comportamiento de salida local en la ejecución de Bake, ejecuta el target por plataforma cuando es necesario y fusiona el resultado en un único artefacto de cara al emisor.
Por qué funciona esta arquitectura
Rendimiento
La mejora de rendimiento proviene de la distribución nativa por plataformas (platform fan-out), la configuración compartida de BuildKit y el manejo centralizado de la caché. El trabajo multiplataforma se puede distribuir en runners compatibles alojados en GitHub en lugar de forzar a cada arquitectura a ejecutarse en una sola máquina de compilación. Esto reduce la presión de emulación, acorta la ruta crítica para compilaciones multiplataforma y proporciona a cada repositorio de consumo la misma línea base de compilación optimizada.
Seguridad
El modelo de seguridad proviene de colocar la implementación de la compilación en flujos de trabajo reutilizables mantenidos por Docker en lugar de pasos de trabajo ad hoc en cada repositorio de consumo. El emisor sigue controlando los permisos y los secretos, pero la lógica de compilación en sí misma se revisa y versiona de forma centralizada. El proyecto también trata la procedencia, la generación de SBOM y la firma como aspectos de primer nivel, lo que fortalece el límite de confianza entre la orquestación del repositorio y la producción de artefactos.
Aislamiento y confiabilidad
La confiabilidad proviene de la separación de conceptos. El repositorio de consumo orquesta la compilación. El flujo de trabajo reutilizable ejecuta la compilación. Esto reduce la desviación de CI (CI drift), elimina el código repetitivo de integración de los repositorios y hace que el resultado sea más fácil de razonar porque el emisor ve un contrato estable en lugar de una gran definición de trabajo personalizada.