Docker Buildx: builders, платформы и экспорт через --load и --push
Автор: Казачкин Даниил Михайлович · Обновлено
Buildx — Docker CLI-плагин для работы с BuildKit. Builder — выбранная среда, которая выполняет сборку; её драйвер определяет возможности и способ передачи результата. Образ может успешно собраться и при этом не появиться в docker images, если результат остался только в кэше отдельного builder.
Инвентаризация перед сборкой
docker buildx version
docker buildx ls
docker buildx inspectПосмотрите имя выбранного builder, driver и поддерживаемые платформы. Драйвер docker встроен в Engine; docker-container запускает отдельный BuildKit-контейнер. Не меняйте выбор builder в рабочем проекте только ради повторения урока: параметр --builder ИМЯ позволяет явно выбрать его для одной команды. Драйверы сборки.
Создадим отдельный учебный builder без глобального переключения:
docker buildx create --name dk-builder --driver docker-container
docker buildx inspect dk-builder --bootstrapВторая команда запускает среду сборки и может скачать образ BuildKit. Имя должно быть свободно. Если такой builder уже существует, выясните его назначение или выберите другое имя; не удаляйте чужую среду.
Локальный образ через --load
Используйте Dockerfile с Alpine и message.txt из урока о build context. Для одной платформы, соответствующей вашей машине, выполните:
docker buildx build --builder dk-builder --load -t dk-buildx:1 .
docker image inspect dk-buildx:1 --format '{{.Id}}'
docker run --rm dk-buildx:1--load передаёт результат в локальное хранилище Docker; после него тег доступен для run. Для отдельного builder это снимает частую неоднозначность «build успешен, а образа нет». Не рассчитывайте, что любой драйвер экспортирует результат одинаково. Экспорт buildx build.
Платформа не равна тегу
linux/amd64 и linux/arm64 описывают ОС и архитектуру. Один тег registry может указывать на индекс с образами нескольких платформ. При pull клиент выбирает подходящий вариант. Классическое локальное image store имеет ограничения для хранения multi-platform результата; возможности containerd image store и конкретного exporter проверяйте отдельно.
Сборка чужой архитектуры может требовать эмуляции, нативного узла builder или кросс-компиляции. Сам флаг --platform не устанавливает эмулятор и не гарантирует, что команда RUN сможет выполниться на текущем хосте. Стратегии multi-platform.
Кросс-компиляция Go
Для main.go из multi-stage урока можно заменить Dockerfile:
FROM --platform=$BUILDPLATFORM golang:1.26-alpine AS build
ARG TARGETOS
ARG TARGETARCH
WORKDIR /src
COPY main.go ./main.go
RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o /out/server ./main.go
FROM scratch
COPY --from=build /out/server /server
USER 10001:10001
ENTRYPOINT ["/server"]Компилятор работает на BUILDPLATFORM, но создаёт бинарник для TARGETOS/TARGETARCH. В таком простом приложении не нужно исполнять целевой бинарник во время сборки. Для cgo и нативных библиотек понадобятся дополнительные инструменты и проверка совместимости.
Отправка в свой registry
После входа в свой реестр и замены YOUR_NAMESPACE выполните:
docker buildx build --builder dk-builder --platform linux/amd64,linux/arm64 -t YOUR_NAMESPACE/dk-server:1 --push .
docker buildx imagetools inspect YOUR_NAMESPACE/dk-server:1--push публикует результат; это уже сетевое изменение в указанном репозитории. Ожидайте обе платформы в inspect. Публикация не загружает автоматически этот тег в локальный image store. Для учебного запуска на ноутбуке достаточно отдельной одноплатформенной сборки с --load; не требуется создавать публичный репозиторий.
Диагностика и практика
При exec format error сравните архитектуру образа, машины и бинарника. При no match for platform in manifest проверьте, публикует ли базовый образ нужный вариант. Если локальный run пытается скачать собственный только что собранный тег, проверьте exporter и контекст Engine.
Соберите один образ через dk-builder с --load, запустите его и запишите driver. После работы удалите только созданный builder: docker buildx rm dk-builder. Его кэш будет потерян, поэтому это завершение учебного эксперимента, а не универсальная диагностика. Локально загруженный образ имеет отдельный жизненный цикл.