Собираем Docker-образы для разных платформ

Привет, друзья! Сегодня расскажу о том, как собрать Docker-образ, который будет работать на разных архитектурах процессоров. Это особенно актуально сейчас, когда ARM-процессоры становятся всё популярнее (Apple M1/M2, Raspberry Pi, Ampere и т.д.).

Зачем это нужно?

Представьте ситуацию: вы разработали приложение на своем ноутбуке с Intel/AMD процессором (архитектура x86_64), а потом хотите запустить его на очередном одноплатнике на arm (мой случай). Если вы просто соберете Docker-образ на своем ноутбуке и попытаетесь запустить его на Raspberry Pi, то получите ошибку. Почему? Потому что бинарные файлы, скомпилированные для x86_64, не будут работать на ARM.

Решение? Создание мультиархитектурных образов

Docker Buildx на помощь

В Docker есть отличный инструмент — Buildx, который позволяет собирать образы для разных платформ одной командой. Давайте разберемся, как им пользоваться.

Шаг 1: Проверяем, что Buildx установлен

docker buildx version

Если вы видите информацию о версии, значит всё в порядке. Если нет, то в современных версиях Docker Buildx уже включен, просто нужно его активировать:

docker buildx create --name mybuilder --use

Шаг 2: Создаем простой Dockerfile

Для примера возьмем простое приложение на Python:

FROM python:3.9-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt

COPY app.py .

CMD ["python", "app.py"]

Шаг 3: Собираем образ для нескольких платформ

Теперь самое интересное. Вместо обычной команды docker build используем docker buildx build:

docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t username/myapp:latest --push .

Что здесь происходит:

  • --platform указывает, для каких платформ собирать образ
  • -t username/myapp:latest задает имя и тег образа
  • --push сразу отправляет образ в Docker Hub (для этого нужно сначала выполнить docker login)

Шаг 4: Проверяем результат

После успешной сборки и отправки в репозиторий, можно проверить, что образ действительно поддерживает разные платформы:

docker manifest inspect username/myapp:latest

Вы увидите список всех платформ, для которых собран образ.

Как это работает под капотом?

Когда вы запускаете docker buildx build для нескольких платформ, Docker:

  1. Запускает виртуальные машины или контейнеры с QEMU для эмуляции целевых архитектур
  2. Собирает образ для каждой указанной платформы
  3. Создает манифест, который объединяет все эти образы
  4. Когда пользователь запускает docker pull, Docker автоматически выбирает подходящий образ для его платформы

Тонкости использования

1. Используйте базовые образы с поддержкой нужных платформ

Не все базовые образы доступны для всех архитектур. Перед использованием проверьте, что выбранный вами базовый образ поддерживает нужные платформы.

2. Учитывайте зависимости

Некоторые библиотеки или инструменты могут не работать на определенных архитектурах. Проверяйте совместимость заранее.

3. Тестируйте на реальном железе

Эмуляция не всегда идеальна. По возможности тестируйте свои образы на реальных устройствах с разными архитектурами.

Заключение

Мультиархитектурные Docker-образы — это мощный инструмент, который позволяет создавать действительно переносимые приложения. Теперь вы можете собрать образ один раз и запускать его где угодно: на своем ноутбуке, на сервере в облаке, на Raspberry Pi или даже на экзотическом оборудовании.

В следующих постах расскажу о том, как автоматизировать такие сборки с помощью GitHub Actions или GitLab CI.


P.S. А вы уже используете мультиархитектурные образы в своих проектах? Расскажите о своем опыте!