Поиск по сайту:

Как использовать Docker Buildx Bake для создания сложных конвейеров сборки образов


Группа команд docker buildx использует BuildKit для предоставления расширенных возможностей сборки образов. Запеченные сборки — это функция высокого уровня, которую можно использовать для определения автоматизированных конвейеров сборки. Они позволяют создавать несколько образов из одной операции сборки.

Запеченные рабочие процессы полезны, когда вы хотите опубликовать различные варианты ваших изображений или создать несколько связанных проектов параллельно. В этой статье мы расскажем об основных функциях docker buildx Bake и о том, как их можно использовать для оптимизации сложных сборок.

Начиная

Команда docker buildx Bake выполняет несколько «целей» сборки, каждая из которых создает образ контейнера. Цели выполняются параллельно, где это возможно, чтобы максимизировать производительность. Цели также могут напрямую ссылаться на предшественников для создания последовательных конвейеров.

Цели сборки можно определить с помощью нескольких различных механизмов, включая существующие файлы Docker Compose. Buildx автоматически создаст все образы, указанные в файле.

Более продвинутые функции доступны, когда вы перечисляете цели сборки в файлах JSON или HCL. Они поддерживают переменные, функции и интерполяцию значений для настройки ваших сборок.

Команда buildx Bake ищет следующие файлы по порядку:

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

Вы можете указать другой файл с флагом команды -f.

Построить цели

Цели сборки инкапсулируют всю конфигурацию, связанную с вашей сборкой. Они включают такие детали, как

  • путь к Dockerfile для сборки
  • создавать контекстные пути, определяя контент, доступный в вашем файле Docker
  • теги и метки для прикрепления к выходным изображениям
  • платформы, для которых создаются изображения.

Полный список поддерживаемых полей конфигурации доступен в документации. Раньше вы могли указать эти параметры в качестве флагов командной строки для docker buildx build (или даже простой docker build), заставляя вас каждый раз запоминать правильные значения. С buildx Bake вы можете надежно использовать одни и те же значения, определив их в запеченном файле с контролируемой версией.

Вот простой пример команды docker-bake.hcl, которая определяет одну цель сборки:

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

Запуск docker buildx Bake с этим файлом Bake загрузит Dockerfile app/Dockerfile из вашего рабочего каталога. Он будет иметь доступ к каталогам app/src и shared-components/src в качестве контекстов сборки. Созданному изображению будут присвоены два тега.

Цель default создается автоматически при запуске docker buildx Bake. Вы также можете определить именованные цели, которые можно создавать по требованию:

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

Использование нескольких целей

Вы можете одновременно создать другое изображение, указав его как новую цель в вашем файле запекания:

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"]
}

Эти образы можно создавать одновременно, поскольку они вложены в группу. Образы api и app будут создаваться параллельно каждый раз, когда вы запускаете команду docker buildx Bake в качестве по умолчанию. группа выбирается автоматически. Вы можете использовать именованные группы аналогично приведенному выше примеру с именованными целями.

Создание целевого наследования

Цели сборки могут наследоваться друг от друга для повторного использования конфигурации. Один из сценариев, в котором это может быть полезно, касается изображений, которые необходимо настроить для разных сред. Возможно, вы захотите добавить дополнительные файлы конфигурации в варианты образа, предназначенные для использования в разработке. Вот docker-bake.hcl, демонстрирующий эту модель:

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"]
}

Цель backend-dev наследует все свойства цели backend, но переопределяет контекст config и применяет другой тег.

Вы можете предварительно просмотреть структуру объединенного файла, запустив команду bake с флагом --print:

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

Использование предыдущей цели в качестве базового изображения

Иногда может потребоваться, чтобы цель сборки использовала образ, созданный предыдущей целью, в качестве собственной базы. Это альтернатива многоэтапным сборкам, которую можно использовать, когда ваши файлы Dockerfile зависят друг от друга, но не могут быть объединены вместе, возможно, потому, что они существуют в разных проектах.

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"]
}

В примере сначала создается цель org-base-image. Он может содержать некоторые утилиты, общие для контейнерных рабочих нагрузок вашей организации. Затем создается цель api с выводом из цели org-base-image, доступной как base build-context. API Dockerfile теперь может ссылаться на содержимое базового образа:

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

Это мощный паттерн, который позволяет создавать связи зависимостей между образами при сохранении отдельных файлов Dockerfile.

Переопределение свойств целей во время сборки

Команда docker buildx Bake позволяет вам переопределять свойства ваших целей при запуске сборки:

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

В этом примере изменяется файл Dockerfile цели api. Подстановочный знак * поддерживается при определении цели для изменения. * сам по себе выбирает каждую цель, в то время как api* изменяет все цели, которые начинаются с api.

Установка переменных

Файлы HCL могут определять переменные, на которые вы можете ссылаться в своих целях сборки. используйте блок variable для их настройки:

variable "TAG" {
    default = "latest"
}

group "default" {
    targets = ["app"]
}

target "app" {
    dockerfile = "src/Dockerfile"
    tags = ["my-app:${TAG}"]
}

Запуск docker buildx Bake с этой конфигурацией пометит цель app как my-app:latest. Вы можете изменить значение переменной TAG, установив переменную среды перед выполнением команды:

$ TAG=v1 docker buildx bake

Вы можете использовать все возможности интерполяции и сравнения переменных языка HCL, чтобы сделать цели сборки пригодными для повторного использования. Также доступны функции для анализа и преобразования ваших значений.

Краткое содержание

Запеченные сборки Buildx позволяют инкапсулировать конфигурацию сборки образа в виде «целей», определенных в файле. Когда вы запускаете buildx Bake, изображения для всех целевых объектов создаются параллельно.

Цели могут наследовать друг друга и зависеть друг от друга. Вы также можете использовать переменные и функции для создания очень сложных и настраиваемых конвейеров сборки.

Команда docker buildx Bake — это высокоуровневая операция, которая не требуется в каждом рабочем процессе. Вам не нужно использовать его, когда вы создаете простые образы без межпроектных зависимостей. Использование docker compose build — лучшая альтернатива для большинства случаев использования, когда конфигурация сборки хранится в вашем файле docker-compose.yml. Переход на запеченные сборки следует рассматривать, когда вы создаете много образов одновременно, используя разные переменные, платформы, контексты сборки и переопределения конфигурации.