Опубликовано 25 февраля 2026 г. •
5 минут •
912 слов
Большинство людей взаимодействуют с BuildKit каждый день, даже не осознавая этого. когда ты бежишь docker buildBuildKit — это движок, стоящий за этим. Но свести BuildKit к «тому, что собирает Dockerfiles» — это все равно, что называть LLVM «того, что компилирует C». Он продает архитектуру по низким ценам в зависимости от объема.
BuildKit — это подключаемая среда сборки общего назначения. Да, он может генерировать образы OCI, а также архивы, локальные каталоги, пакеты APK, RPM или что-то еще, что вы могли бы описать как направленный ациклический граф операций файловой системы. Dockerfile — это всего лишь интерфейс. Вы можете написать свой собственный.
архитектура
BuildKit имеет чистый дизайн и на удивление имеет смысл при просмотре слоев. Есть три основные концепции.
Бакалавр права: промежуточное представительство
BuildKit лежит в основе бакалавр права (определение низкоуровневой сборки). Думайте об этом как о LLVM IR системы сборки. LLB — это двоичный протокол (protobuf), описывающий DAG операций с файловой системой: запуск команды, копирование файлов, монтирование файловой системы. Он адресуется по содержимому, что означает, что аналогичные операции создают один и тот же хэш, что обеспечивает агрессивное кэширование.
Когда вы пишете Dockerfile, интерфейс Dockerfile анализирует его и выдает LLB. Но ничто в BuildKit не требует, чтобы входные данные были Dockerfile. Любая программа, которая может генерировать действительный LLB, может запускать BuildKit.
Интерфейс: добавьте свой собственный синтаксис
А внешний интерфейс Существует образ контейнера, который BuildKit запускает для преобразования вашего определения сборки (Dockerfile, YAML, JSON, HCL и т. д.) в LLB. Интерфейсная часть получает контекст сборки и файл сборки через API BuildKit Gateway и возвращает упорядоченный граф LLB.
Это ключевой вывод: язык сборки не встроен в BuildKit. Это подключаемый слой. Вы можете написать интерфейс, который считывает спецификацию YAML, конфигурацию TOML или собственный DSL, и BuildKit будет выполнять его так же, как он выполняет Dockerfiles.
Вы уже видели этот механизм раньше. # syntax= Директива в верхней части Dockerfile сообщает BuildKit, какой образ внешнего интерфейса использовать. # syntax=docker/dockerfile:1 Просто по умолчанию. Вы можете указать его на любое изображение.
Решатель и кэш: выполнение с адресацией по содержимому
решатель LLB берет граф и выполняет его. Каждая вершина в DAG имеет адресацию по содержимому, поэтому, если вы уже создали определенный шаг с похожими входными данными, BuildKit полностью его пропускает. Вот почему BuildKit быстрее: он не кэширует слои линейно, как старый Docker Builder. Он кэшируется на уровне операций по всему графу и может параллельно выполнять независимые ветви.
Кэш может быть локальным, встроенным (встроенным в образ) или удаленным (реестр). Это делает BuildKit воспроизводимым и доступным для всех участников CI.
┌─────────────┐ ┌──────────┐ ┌────────┐ ┌─────────┐ ┌────────────┐
│ Your spec │───▶│ Frontend │───▶│ LLB │───▶│ Solver │───▶│ Output │
│ (YAML, HCL, │ │ (Gateway │ │ (DAG) │ │ (cache, │ │ (image, │
│ Dockerfile)│ │ client) │ │ │ │ execute)│ │ tarball, │
└─────────────┘ └──────────┘ └────────┘ └─────────┘ │ local dir) │
└────────────┘
не просто изображения
комплект для сборки --output Флаг — это то место, где это становится практичным. Вы можете указать BuildKit экспортировать результаты следующим образом:
type=image– Отправить в реестр (по умолчанию дляdocker build)type=local,dest=./out– Дамп последней файловой системы в локальный каталогtype=tar,dest=./out.tar– Экспортировать как tarballtype=oci– Экспортировать в архив изображений OCI.
type=local Результат наиболее интересен для случаев использования, не связанных с изображениями. Ваша сборка может генерировать скомпилированные двоичные файлы, пакеты, документацию или что-то еще, а BuildKit сохранит результаты на диск. Образ контейнера не требуется.
Такие проекты, как Earthly, Dagger и Depot, построены на основе LLB Buildkit. Это проверенная закономерность.
Создание пакета APK с пользовательским интерфейсом
Чтобы продемонстрировать это конкретно, я создал APKBuild: собственный интерфейс BuildKit, который считывает спецификацию YAML и генерирует пакеты Alpine APK. Dockerfile не включен. Весь конвейер сборки — от компиляции исходного кода до упаковки APK — выполняется внутри BuildKit с использованием операций LLB. Думайте об этом как о фиктивной версии «Меланжа» Chainguard.
Я выбрал YAML для ознакомления, но спецификация может быть любой, какой вы захотите (JSON, TOML, собственный DSL), если ваш интерфейс может ее проанализировать.
YAML-описание моего пакета выглядит так:
name: hello
version: "1.0.0"
epoch: "0"
url: https://example.com/hello
license: MIT
description: Minimal CMake APK demo
sources:
app:
context: {}
build:
source_dir: hello
Вот и все. Нет Докерфайла. Нет сценария оболочки. BuildKit считывает эту спецификацию через специальный интерфейс и создает .apk файл.
за рулем
Создайте изображение внешнего интерфейса:
docker build -t tuananh/apkbuild -f Dockerfile .
Затем используйте это для создания пакета APK:
cd example
docker buildx build \
-f spec.yml \
--build-arg BUILDKIT_SYNTAX=tuananh/apkbuild \
--output type=local,dest=./out \
.
Вы должны увидеть пакет APK out папка, как показано ниже

BUILDKIT_SYNTAX Сообщает BuildKit использовать наш собственный интерфейс вместо парсера Dockerfile по умолчанию. --output type=local сбрасывает результат .apk к файлам ./out. Изображение не формируется. Никакой реестр не задействован.
Почему это важно?
BuildKit бесплатно предоставляет вам параллельный кэшированный механизм сборки с адресацией по содержимому. Вам не нужно заново изобретать кэширование, параллелизм или воспроизводимость. Вы пишете интерфейс, который преобразует вашу спецификацию в LLB, а BuildKit делает все остальное.
Это актуально не только для демонстрации игрушек. Dagger использует LLB в качестве механизма выполнения для конвейеров CI/CD. Earthly компилирует Earthfiles в LLB. Модель доведена до совершенства в масштабе.
Если вы создаете инструмент, требующий компиляции кода, создания артефактов или организации многоэтапных сборок, рассмотрите BuildKit в качестве серверной части выполнения. Dockerfile — это просто интерфейс по умолчанию. Реальная мощность находится в двигателе внизу.