Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як прискорити збирання образу для іншої архітектури: емуляція, нативні збирачі й TARGETARCH?

Збирання arm64-образу на x86-машині (чи навпаки) через емуляцію QEMU працює «прозоро», але кожна інструкція RUN виконується в емульованому процесорі. Компіляція PHP-розширень (docker-php-ext-install, pecl install), нативних npm-модулів чи npm run build може сповільнитися в 5-20 разів - збирання на хвилини перетворюється на збирання на пів години.

Варіанти прискорення:

1. Нативні збирачі для кожної архітектури. Кожна платформа збирається на своєму залізі, результати об'єднуються в один мультиплатформний образ:

  • buildx з кількома вузлами: docker buildx create --name multi --platform linux/amd64 ssh://amd-builder і --append вузол linux/arm64;
  • CI з матрицею - arm64-раннери (у GitHub Actions доступні) збирають arm64, amd64-раннери - amd64; окремий крок створює індекс (docker buildx imagetools create);
  • хмарні збирачі (Docker Build Cloud та інші) з нативними вузлами обох архітектур.

2. Виконувати незалежні від архітектури кроки на рідній платформі збирача. Збирання фронтенду дає однаковий результат (JS, CSS) для будь-якої архітектури - немає сенсу емулювати його:

# syntax=docker/dockerfile:1
FROM --platform=$BUILDPLATFORM node:22-alpine AS assets
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build                      # виконується нативно один раз

FROM php:8.5-fpm-alpine                # цільова платформа
COPY --from=assets /app/public/build /var/www/html/public/build

--platform=$BUILDPLATFORM змушує етап виконуватися на архітектурі збирача.

3. Крос-компіляція - для мов, що вміють збирати під іншу архітектуру (Go, Rust): етап на $BUILDPLATFORM компілює бінарник для $TARGETOS/$TARGETARCH, а фінальний етап його лише копіює.

Вбудовані змінні BuildKit: BUILDPLATFORM, TARGETPLATFORM, TARGETOS, TARGETARCH, TARGETVARIANT - щоб, наприклад, завантажити бінарник потрібної архітектури:

ARG TARGETARCH
RUN curl -fsSL -o /usr/local/bin/tool "https://example.com/tool-linux-${TARGETARCH}"

Пастки:

  • кеш для кожної платформи окремий - експорт кешу в CI має покривати обидві;
  • залежності Composer з нативними частинами зазвичай немає (PHP-код незалежний від архітектури), тож composer install теж можна винести на $BUILDPLATFORM (з --ignore-platform-reqs чи узгодженими розширеннями);
  • тестування образу кожної архітектури - емуляція під час збирання не гарантує, що розширення поводяться однаково.

Докладніше в документації: Мультиплатформні збирання: крос-компіляція

Схожі питання