Cómo utilizar Docker Buildx Bake para crear canalizaciones de creación de imágenes complejas

Publicado: 2022-08-10

Gráfico que muestra el logotipo de Docker

El grupo de comandos docker buildx usa BuildKit para exponer capacidades avanzadas de creación de imágenes. Las compilaciones horneadas son una característica de alto nivel que se puede usar para definir canalizaciones de compilación automatizadas. Le permiten producir múltiples imágenes a partir de una sola operación de construcción.

Los flujos de trabajo horneados son útiles cuando desea publicar diferentes variantes de sus imágenes o crear varios proyectos vinculados en paralelo. En este artículo, cubriremos las características clave de docker buildx bake y cómo puede usarlas para simplificar compilaciones complejas.

Empezando

El comando docker buildx bake ejecuta varios "objetivos" de compilación, cada uno de los cuales produce una imagen de contenedor. Los objetivos se ejecutan en paralelo siempre que sea posible para maximizar el rendimiento. Los objetivos también pueden hacer referencia directamente a los predecesores para crear canalizaciones secuenciales.

Los objetivos de compilación se pueden definir mediante varios mecanismos diferentes, incluidos los archivos de Docker Compose existentes. Buildx construirá automáticamente todas las imágenes identificadas en el archivo.

Se exponen funciones más avanzadas cuando enumera los objetivos de compilación en archivos JSON o HCL. Estos admiten variables, funciones e interpolación de valores para personalizar sus compilaciones.

El comando buildx bake busca los siguientes archivos en orden:

  • docker-compose.yml
  • docker-compose.yaml
  • docker-bake.json
  • docker-bake.override.json
  • docker-bake.hcl
  • docker-bake.override.hcl

Puede especificar un archivo diferente con el indicador de comando -f .

Construir objetivos

Los objetivos de compilación encapsulan toda la configuración relacionada con su compilación. Incluyen detalles como

  • la ruta al Dockerfile para construir
  • construir rutas de contexto, definiendo el contenido disponible dentro de su Dockerfile
  • etiquetas y rótulos para adjuntar a las imágenes de salida
  • las plataformas para producir imágenes.

Una lista completa de los campos de configuración admitidos está disponible en la documentación. Anteriormente, es posible que haya proporcionado esta configuración como indicadores de línea de comandos para docker buildx build (o incluso simple docker build ), lo que le obligaba a recordar los valores correctos cada vez. Con buildx bake , puede usar de manera confiable los mismos valores definiéndolos en su archivo horneado controlado por versión.

Aquí hay un ejemplo simple de un comando docker-bake.hcl que define un solo objetivo de compilación:

 target "default" { dockerfile = "app/Dockerfile" contexts = { app = "app/src" shared = "shared-components/src" } tags = ["my-app:latest", "docker.io/my-org/my-app:latest"] }

Al ejecutar docker buildx bake con este archivo de horneado, se cargará la app/Dockerfile Dockerfile desde su directorio de trabajo. Tendrá acceso a los directorios app/src y shared-components/src como contextos de compilación. A la imagen que se produce se le asignarán dos etiquetas.

El objetivo default se crea automáticamente cuando ejecuta docker buildx bake . También puede definir objetivos con nombre que se pueden construir a pedido:

 target "app" { // ... }
 $ docker buildx bake app

Uso de objetivos múltiples

Puede crear otra imagen simultáneamente definiéndola como un nuevo objetivo dentro de su archivo de horneado:

 group "default" { targets = ["app", "api"] } target "app" { dockerfile = "app/Dockerfile" contexts = { app = "app/src" shared = "shared-components/src" } tags = ["my-app:latest", "docker.io/my-org/my-app:latest"] } target "api" { dockerfile = "api/Dockerfile" contexts = { src = "api/src" } tags = ["my-api:latest", "docker.io/my-org/my-api:latest"] }

Estas imágenes se pueden construir simultáneamente porque están anidadas en un grupo. Las imágenes de la api y la app se compilarán en paralelo cada vez que ejecute el comando docker buildx bake , ya que el grupo default se selecciona automáticamente. Puede usar grupos con nombre de manera similar al ejemplo de objetivos con nombre anterior.

Crear herencia de destino

Los objetivos de compilación pueden heredar unos de otros para reutilizar la configuración. Un escenario en el que esto puede ser útil se refiere a las imágenes que deben personalizarse para diferentes entornos. Es posible que desee agregar archivos de configuración adicionales a las variantes de imagen destinadas al uso de desarrollo. Aquí hay un docker-bake.hcl que demuestra este modelo:

 group "default" { targets = ["backend", "backend-dev"] } target "backend" { dockerfile = "backend/Dockerfile" contexts = { src = "api/src" config = "api/config" } tags = ["backend:latest"] } target "backend-dev" { inherits = ["backend"] contexts = { config = "api/config-dev" } tags = ["backend:dev"] }

El objetivo backend-dev hereda todas las propiedades del objetivo backend pero anula el contexto de config y aplica una etiqueta diferente.

Puede obtener una vista previa de la estructura de archivos combinados ejecutando el comando bake con el indicador --print :

 $ docker buildx bake --print ... "backend-dev": { "context": ".", "contexts": { "config": "api/config-dev", "src": "api/src" }, "dockerfile": "backend/Dockerfile", "tags": [ "backend:dev" ] } ...

Uso de un destino anterior como imagen base

A veces, es posible que desee que un destino de compilación use la imagen creada por un destino anterior como su propia base. Esta es una alternativa a las compilaciones de varias etapas que se pueden usar cuando sus Dockerfiles dependen unos de otros pero no se pueden fusionar, quizás porque existen en diferentes proyectos.

 group "default" { targets = ["org-base-image", "api"] } target "org-base-image" { dockerfile = "docker-base/Dockerfile" tags = ["org-base-image:latest"] } target "api" { dockerfile = "api/Dockerfile" contexts = { base = "target:org-base-image" } tags = ["api:latest"] }

El ejemplo primero crea el objetivo org-base-image la organización. Esto podría contener algunas utilidades que son comunes a las cargas de trabajo en contenedores de su organización. Luego, el objetivo de la api se crea con la salida del objetivo org-base-image la organización accesible como contexto de compilación base . El API Dockerfile ahora puede hacer referencia al contenido dentro de la imagen base:

 COPY --from=base /utilities/example /usr/bin/example-utility

Este es un patrón poderoso que le permite crear vínculos de dependencia entre imágenes mientras mantiene Dockerfiles separados.

Anulación de las propiedades de los destinos en el momento de la compilación

El comando docker buildx bake le permite anular las propiedades de sus objetivos cuando ejecuta su compilación:

 $ docker buildx bake --set api.dockerfile="api/Dockerfile-dev"

Este ejemplo cambia el Dockerfile del destino de la api . Se admite el comodín * al identificar el objetivo que se va a cambiar. * por sí solo selecciona todos los objetivos, mientras que api* modificará todos los objetivos que comienzan con api .

Configuración de variables

Los archivos HCL pueden definir variables a las que puede hacer referencia en sus objetivos de compilación. use un bloque variable para configurarlos:

 variable "TAG" { default = "latest" } group "default" { targets = ["app"] } target "app" { dockerfile = "src/Dockerfile" tags = ["my-app:${TAG}"] }

Ejecutar docker buildx bake con esta configuración etiquetará el destino de la app como my-app:latest . Puede cambiar el valor de la variable TAG configurando una variable de entorno antes de ejecutar el comando:

 $ TAG=v1 docker buildx bake

Puede usar todas las capacidades de interpolación y comparación de variables del lenguaje HCL para hacer que sus objetivos de compilación sean reutilizables. Las funciones también están disponibles para analizar y transformar sus valores.

Resumen

Las compilaciones Baked Buildx le permiten encapsular la configuración de compilación de imágenes como "objetivos" definidos en un archivo. Cuando ejecuta buildx bake , las imágenes para todos los objetivos a los que se hace referencia se crean en paralelo.

Los objetivos pueden heredar y depender unos de otros. También puede usar variables y funciones para crear canalizaciones de compilación altamente complejas y configurables.

El comando docker buildx bake es una operación de alto nivel que no es necesaria en todos los flujos de trabajo. No necesita usarlo cuando está creando imágenes simples sin dependencias entre proyectos. Usar docker compose build es una mejor alternativa para la mayoría de los casos de uso que mantiene la configuración de compilación en su archivo docker-compose.yml . Se debe considerar el cambio a compilaciones horneadas cuando está compilando muchas imágenes simultáneamente usando diferentes variables, plataformas, contextos de compilación y anulaciones de configuración.