Збирання 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чи узгодженими розширеннями); - тестування образу кожної архітектури - емуляція під час збирання не гарантує, що розширення поводяться однаково.
Докладніше в документації: Мультиплатформні збирання: крос-компіляція