При развертывании Python приложений в среде Docker, вы часто сталкиваетесь с тем, что время сборки образа слишком долгое или сборка завершается неудачно из-за проблем с зависимостями компилятора, такими как gcc. Одним из самых эффективных решений является использование Python Wheel.

В этой статье мы рассмотрим концепцию и преимущества Python Wheel, а также как оптимизировать процесс сборки, используя его в Dockerfile.


1. Что такое Python Wheel?



Wheel(.whl) — это формат бинарного распространения Python (Built Distribution).

Обычно Python пакеты распространяются в двух формах.

  1. Source Distribution (sdist, .tar.gz): это форма исходного кода. При установке процесс сборки необходим на компьютере пользователя.

  2. Built Distribution (bdist_wheel, .whl): это предварительно скомпилированная бинарная форма. При установке нужно только скопировать файлы, и установка завершена.

Если говорить в упрощенном виде, то исходный дистрибутив — это 'мебель, которую нужно собрать', а Wheel — это 'готовая мебель'. При использовании Wheel вам не нужно время на сборку и инструменты (компиляторы).


2. Отличия от обычного pip install

Когда мы выполняем команду pip install <package>, она работает внутренне по следующему приоритету.

  1. Если файл Wheel существует: бинарный файл загружается и устанавливается сразу. (очень быстро)

  2. Если файла Wheel нет: загружается исходный файл (tar.gz), затем производится сборка в локальной среде и установка. (медленно, нужен инструмент компиляции)

Сводная таблица отличий

Категория Source Distribution (sdist) Wheel (whl)
Расширение .tar.gz, .zip .whl
Процесс установки Загрузка -> Компиляция -> Установка Загрузка -> Установка
Скорость установки Медленно (требуется время на компиляцию) Очень быстро
Необходимые инструменты Компилятор (gcc, g++, заголовочные файлы и т.д.) Нет (достаточно pip)
Зависимость от ОС Зависит от среды компиляции Зависит от собранной ОС/архитектуры

3. Причины использования Wheel в Dockerfile (преимущества)



Использование Wheel в среде Docker, особенно в многоэтапной сборке (Multi-stage Build), имеет явные преимущества.

  1. Резкое увеличение скорости сборки: больше не нужно каждый раз компилировать тяжелые библиотеки, такие как pandas и numpy, которые написаны на C/C++.

  2. Уменьшение размера образа: в конечный исполняемый образ (Runtime Image) не нужно включать тяжелые инструменты компиляции, такие как gcc и build-essential.

  3. Обеспечение стабильности: предотвращает сбои во время сборки из-за сетевых проблем или временных сбоев внешнего хранилища и позволяет использовать заранее скомпилированные файлы локально.


4. Написание и использование Dockerfile

Сборка Docker с использованием Wheel в основном осуществляется следующим образом: создаются файлы Wheel на этапе сборщика (Builder stage), а затем они переносятся и устанавливаются на финальном этапе (Final stage).

Пример: Dockerfile с использованием многоэтапной сборки

Ниже приведен шаблон для эффективной установки пакета с зависимостями от библиотеки C.

# [Этап 1] Сборщик: создание Wheel файла
FROM python:3.9-slim as builder

# Установка обязательных пакетов для компиляции (не включается в окончательный образ)
RUN apt-get update && apt-get install -y \
    build-essential \
    gcc \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Копирование requirements.txt
COPY requirements.txt .

# Создание .whl файлов в директории /wheels командой pip wheel
# -w: Это указывает путь к сохранению wheel файлов
RUN pip wheel --no-cache-dir --no-deps --wheel-dir /app/wheels -r requirements.txt


# [Этап 2] Финальный: исполняемый образ
FROM python:3.9-slim

WORKDIR /app

# Копирование только созданных в этапе сборщика Wheel файлов
COPY --from=builder /app/wheels /wheels
COPY --from=builder /app/requirements.txt .

# Установка пакетов с использованием Wheel файлов
# --no-index: Игнорирует индекс PyPI и ищет только локальные файлы
# --find-links: Указывает пути, где искать устанавливаемые пакеты
RUN pip install --no-cache --no-index --find-links=/wheels -r requirements.txt \
    && rm -rf /wheels

# Копирование кода приложения
COPY . .

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

Описание ключевых команд

  • pip wheel: Создает файл .whl, соответствующий данной среде, и сохраняет его в указанную директорию без установки пакета.

  • --wheel-dir: Место, куда будет сохранен созданный Wheel файл.

  • --find-links=/wheels: Указывает искать пакеты в указанном локальном пути вместо загрузки с сервера PyPI (Интернет).


Заключение

Использование Python Wheel при сборке Docker — это не просто выбор, это необходимая оптимизация. Особенно в среде CI/CD, где происходит повторяющаяся сборка, сокращение времени сборки и уменьшение размера образа может привести к значительной экономии средств.

Если в вашем Dockerfile присутствует установка gcc, попробуйте перейти на многоэтапную сборку с использованием Wheel.

python-wheel-concept-image