Baked builds в docker buildx — параллельные сборки образов

Важно: baked builds — это инструмент высокого уровня, не всегда необходимый для простых образов. Для однострочных или простых сборок иногда достаточно docker build или docker compose build.
Краткие определения
- Baked build: набор заранее описанных целей (targets) сборки в файле конфигурации (HCL/JSON/Compose). Позволяет запускать несколько сборок как единый процесс.
- Target: единичная конфигурация сборки, содержащая Dockerfile, контексты, теги, платформы и т.п.
- Контекст (build context): набор файлов, доступных Dockerfile во время сборки.
Начало работы
Команда “docker buildx bake” использует BuildKit для расширенной сборки образов. Она запускает все цели, перечисленные в файле bake, и старается выполнить их параллельно, если зависимости это позволяют.
По умолчанию buildx ищет файлы в таком порядке:
- docker-compose.yml
- docker-compose.yaml
- docker-bake.json
- docker-bake.override.json
- docker-bake.hcl
- docker-bake.override.hcl
Если нужно — можно указать другой файл флагом -f.
Простой сценарий: вы храните конфигурацию сборки в docker-bake.hcl и запускаете docker buildx bake в CI или локально. Это гарантирует согласованность параметров сборки и удобство версионирования.
Что такое цели сборки (Build Targets)
Цель сборки (target) содержит:
- путь к Dockerfile
- контексты сборки (пути к исходникам и shared-компонентам)
- теги и метаданные
- платформы (например, linux/amd64, linux/arm64)
Раньше эти параметры часто передавались в командной строке docker buildx build или docker build. Baked builds позволяют хранить их в одном месте — в файле, который можно коммитить в репозиторий.
Пример простого 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 с этим файлом загрузит app/Dockerfile из рабочей директории и предоставит Dockerfile доступ к app/src и shared-components/src. Результирующий образ получит два тега.
Запуск именованных целей и групп
По умолчанию автоматически выбирается цель или группа с именем default. Вы можете определить другие цели и запускать их по имени:
$ 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"]
}Группа позволяет BuildKit запускать api и app параллельно при отсутствии явных зависимостей.
Наследование целей
Цели могут наследоваться друг от друга для переиспользования конфигурации. Это удобно для вариаций образов (например, prod/dev).
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"]
}Запуск с --print покажет объединённую (merged) конфигурацию и удобен для отладки:
$ docker buildx bake --printИспользование результата предыдущей цели как базового образа
Иногда нужно, чтобы одна цель использовала образ, собранный другой целью, как базу. Это альтернатива multi-stage, когда 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"]
}В Dockerfile цели “api” можно ссылаться на данные из “base”:
COPY --from=base /utilities/example /usr/bin/example-utilityЭто позволяет организовать зависимость между образами без слияния Dockerfile.
Переопределение свойств при запуске
Вы можете менять параметры цели при выполнении bake:
$ docker buildx bake --set api.dockerfile="api/Dockerfile-dev"Поддерживаются подстановки звездочкой * при выборе целей. * сам по себе выберет все цели, api* — все цели, начинающиеся на “api”.
Переменные и параметризация
Файлы HCL поддерживают блоки переменных. Это делает цели повторно используемыми и удобными для CI.
variable "TAG" { default = "latest" }
group "default" { targets = ["app"] }
target "app" {
dockerfile = "src/Dockerfile"
tags = ["my-app:${TAG}"]
}Значение можно переопределить через ENV:
$ TAG=v1 docker buildx bakeHCL поддерживает функции, сравнения и интерполяцию значений.
Когда baked builds полезны (и когда не нужны)
Используйте baked builds, если:
- вам нужно собирать сразу много связанных образов;
- есть общие контексты и ресурсы между проектами;
- требуется кросс-платформенная сборка (amd64/arm64);
- нужно переиспользовать собранные образы как базу для других целей.
Не обязательно использовать baked builds, если:
- проект прост и содержит один Dockerfile;
- вы предпочитаете хранить конфигурацию сборки только в docker-compose.yml без дополнительной логики;
- ваша CI-пайплайн не требует параллельных или зависимых сборок.
Альтернативы
- docker compose build — простое решение, если вы уже используете docker-compose и не нужны продвинутые возможности BuildKit.
- Простые
docker buildx buildкоманды в CI, если количество образов невелико. - Интеграция сборки в специализированные инструменты (Task runner, Bazel) при очень крупных монорепозиториях.
Ментальные модели и эвристики
- Подумайте о baked файле как о «плане референтных сборок» — он описывает что, где и как собирать.
- Группы — это “пакеты сборок”; цели внутри группы — независимые или сопоставимые задачи.
- Наследование — способ DRY (Dont Repeat Yourself) для конфигурации.
- Контекст “target:NAME” — сигнал, что вы используете артефакты другой цели как базу.
Decision tree — стоит ли переходить на baked builds?
flowchart TD
A[У вас >1 образов?] -->|Да| B{Образы связаны между собой?}
A -->|Нет| Z[Останьтесь с docker build/compose]
B -->|Да| C{Нужна ли кросс-платформенная сборка или переиспользование образов?}
B -->|Нет| Z
C -->|Да| D[Использовать docker buildx bake]
C -->|Нет| E[docker compose build или индивидуальные buildx команды]Cheat sheet — часто используемые флаги и приёмы
-f— указать файл bake--print— вывести объединённую конфигурацию без запуска сборки--set— переопределение в CLI. = TAG=v1 docker buildx bake— передача переменных через окружениеcontexts = { base = "target:org-base-image" }— использование предыдущей цели как контекста
Playbook: миграция на baked builds (шаги)
- Соберите инвентаризацию Dockerfile и образов.
- Создайте базовый
docker-bake.hcl, определите базовые цели и теги. - Объедините общие контексты, вынесите повторяющиеся значения в переменные.
- Добавьте группы для логических наборов сборки (backend, frontend, infra).
- Протестируйте локально с
--printи затемdocker buildx bake --load. - Интегрируйте в CI, установите builder с нужными платформами.
- Постепенно заменяйте ad-hoc скрипты на
bakeвызовы.
Ролевые чек-листы перед запуском bake
Разработчик:
- Убедиться, что Dockerfile хорошо кэшируются и минимальны.
- Проверить, что контексты включают только нужные файлы.
- Протестировать отдельную цель локально.
Инженер CI/CD:
- Настроить buildx builder и зарегистрировать платформы.
- Добавить шаги
docker buildx bakeс нужными флагами и секретами. - Настроить кеширование и артефакт-репозитории.
Релиз-инженер:
- Определить теги и политику версионирования.
- Обеспечить безопасность хранилищ образов и прав на пуш.
Критерии приёмки
- Все цели успешно собираются локально и в CI.
- Теги соответствуют принятой политике релизов.
- Время сборки и использование ресурсов находятся в допустимых пределах.
- Документация по bake файлам обновлена в репозитории.
Примеры ошибок и места, где модель может не подойти
- Если Dockerfile используют слишком большой контекст (включают .git или node_modules), сборки будут медленными.
- Если разные цели требуют разных builder’ов или настроек хоста, единый
bakeможет быть неудобен.
Шаблон проверки и тестовые случаи
- Тест 1:
docker buildx bake --printдолжен вывести ожидаемые поля для каждой цели. - Тест 2:
docker buildx bake --loadдолжен собрать образы и поместить их в локальный daemon (при необходимости). - Тест 3: Переопределение переменной через ENV и через
--setдаёт предсказуемый результат.
Итог
Baked builds в docker buildx дают мощный, декларативный способ описать и выполнить множество связанных сборок образов. Они особенно полезны при сборке нескольких версий образов, при организации зависимостей между проектами и при кросс-платформенной сборке. Для простых сценариев можно оставаться с docker build или docker compose, но при росте количества образов и усложнении пайплайнов baked builds заметно упрощают поддержку и масштабирование.
- Ключевые преимущества: единая конфигурация, параллельные сборки, наследование, переиспользование артефактов.
- Когда не использовать: одиночные простые сборки или ситуации с несовместимыми требованиями к builder’у.
Смотрите официальную документацию docker buildx для полного списка полей конфигурации и последних возможностей BuildKit.
Похожие материалы
Discord не обновляется в Windows 10 — быстрые исправления
Экспорт контактов iPhone в Windows 10
Тыловые 5.1 колонки не работают после Windows 10
Как недорого работать в дороге — гаджеты и планы
Где находятся файлы конфигурации Apache