Learning Platform
Глоссарий Troubleshooting
Урок 17.01 · 22 мин
Начальный
dockerpythondata-engineering

Выбор base image для Python

Сборка Python-образа начинается с выбора FROM .... Этот выбор определяет: размер образа, скорость сборки, какие зависимости поставятся, безопасность, удобство дебага. Для Junior DE это часто первый момент, где «работает» vs «работает плохо» — потому что выбор python:3.13-alpine для DE-приложения с pandas — это часовое мучение со сборкой.

В этом уроке: разница между python:3.13, python:3.13-slim, python:3.13-alpine, distroless. Почему slim — золотая середина для DE. Когда стоит выходить за рамки.


Что такое base image

Когда ты пишешь FROM python:3.13-slim, Docker тянет образ python:3.13-slim с Docker Hub. Этот образ собран maintainer’ами Python (официальная команда docker-library) и содержит:

  • ОС-базу (Debian / Alpine / другая).
  • Python interpreter нужной версии.
  • pip, setuptools, wheel.
  • Минимальный набор системных библиотек, чтобы Python работал (libssl, libffi, etc.).

Выбор base — это выбор ОС + размера + предустановленных пакетов.


Дистрибутивы Linux: Debian, RHEL, Arch, Alpine

python:3.13 (full)

Размер: ~1 ГБ.
База: Debian 12 (Bookworm), полный.

Что внутри: всё, что есть в debian:12 (gcc, make, git, curl, vim, man-pages, …), плюс Python. Самый «жирный», но удобный для разработки — большая часть build deps уже есть, никаких сюрпризов.

Когда брать: редко. Только если нужны GCC, build-essentials прямо в финальном образе (например, для пересборки native libs во время старта). В 99% случаев избыточен.

FROM python:3.13
# 1 ГБ образ

python:3.13-slim (slim)

Размер: ~150 МБ.
База: Debian 12 slim — Debian с урезанными man-pages, locale, без многих утилит.

Что внутри: Python + минимум системных библиотек. Нет gcc, нет git, нет curl (его надо apt-get install).

Когда брать: большинство DE-приложений. Slim — это compromise между размером и совместимостью. Любая pip-зависимость с native code (psycopg, numpy, pandas, lxml, cryptography) собирается прозрачно — либо есть wheel под manylinux2014 (Debian-compatible), либо собирается через apt-get install build-essential gcc + pip install.

Это стандарт для production-Python в Docker. Когда сомневаешься — берёшь slim.

FROM python:3.13-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
    gcc=4:12.* \
    libpq-dev=15.* \
    && rm -rf /var/lib/apt/lists/*

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

python:3.13-alpine (alpine)

Размер: ~50 МБ.
База: Alpine Linux — минималистичный дистрибутив на musl libc и BusyBox.

Кажется привлекательным: маленький, быстрый. Но musl libc — это ключевая разница, которая ломает Python-экосистему.

Почему alpine плох для DE

Python wheels на PyPI собираются под manylinux — стандарт, который требует glibc (стандартный libc на Linux). Alpine использует musl — альтернативный libc. Они бинарно несовместимы.

Что это значит на практике:

FROM python:3.13-alpine
RUN pip install pandas

pip ищет wheel для pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl. Если есть — отлично, ставит за секунды. Если нет — pip пытается собрать pandas из исходников. Сборка pandas с нуля требует gcc, gfortran, и около 10 минут CPU-времени. Образ распухает с 50 МБ до 700 МБ только за счёт build-tools.

В 2024-2025 ситуация улучшилась — большинство популярных пакетов выпускают musllinux wheels. Но не всё:

  • pandas — есть musl wheel.
  • numpy — есть.
  • scipy — есть.
  • pyarrow — нет musl wheel под все версии. На alpine надо собирать из исходников. Около 20 минут.
  • polars — есть.
  • duckdb — есть.
  • confluent-kafka — собирается с натяжкой.
  • psycopg[c] — есть musl wheel.

Для проекта с pyarrow / sklearn / TensorFlow — alpine лишает тебя сна. Сборка будет занимать 30 минут, образ — 1.5 ГБ (со всеми build-tools).

WARNING

Не используй python:3.13-alpine для DE-проектов, если только не уверен, что все зависимости имеют musllinux-wheels. Меньше размер образа (50 МБ vs 150 МБ slim) не стоит часов сборки и проблем совместимости. Для веб-API без pandas (FastAPI + sqlalchemy + asyncpg) — alpine ОК.


distroless (Google)

Размер: ~50 МБ (python3-debian12).
База: «distroless» — нет shell, нет package manager, только Python и минимум runtime libs.

Что внутри: Python, libssl, libcrypto, libcrypt, libz, тд — всё что Python нужно для работы. Нет sh, нет apt, нет ls.

FROM python:3.13-slim AS builder
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

FROM gcr.io/distroless/python3-debian12
COPY --from=builder /root/.local /root/.local
ENV PATH=/root/.local/bin:$PATH
COPY . /app
WORKDIR /app
ENTRYPOINT ["python", "main.py"]

Distroless обычно используется в multi-stage: builder ставит зависимости, distroless runtime их забирает.

Преимущества:

  • Security: меньше attack surface (нет shell — нечего эксплойтить).
  • Compliance: легче пройти security audit.
  • Размер: 50-100 МБ.

Недостатки:

  • Дебаг сложен: нельзя docker exec -it bash (см. модуль 14 урок 2). Для дебага — :debug-вариант с busybox.
  • Стороннее ПО ставить негде: если приложение хочет вызвать curl — нельзя.
  • Glibc-compatibility issues: основано на debian, так что glibc-wheels работают, но не все мелкие либы.

Когда брать: production-grade образы для прода, когда команда уже умеет дебажить через :debug и nsenter. Для junior — overkill, slim комфортнее.


chainguard images

Размер: ~30-80 МБ.
База: альтернатива distroless от Chainguard, основана на Wolfi (musl + glibc-совместимая ОС, специально под безопасность).

FROM cgr.dev/chainguard/python:latest

Преимущества: минимум CVE (Chainguard сами поддерживают forks популярных пакетов с актуальными патчами), маленький размер, OCI-compliant.

Недостатки: проприетарные source (бесплатна latest, исторические — за деньги). Меньше известно community wise.

Для DE 2026 это активная альтернатива distroless — стоит знать, попробовать в pet-проекте, для production команды решают.


Сравнительная таблица

ОбразРазмерБазовая ОСCVE (типично)Совместимость pipКогда брать
python:3.13~1 ГБDebian full40-60fullНикогда (избыточен)
python:3.13-slim~150 МБDebian slim (glibc)30-50full (glibc, manylinux)Default DE
python:3.13-alpine~50 МБAlpine (musl)10-20musllinux onlyПростые web/CLI
distroless/python3~50 МБDebian (glibc)5-15fullProduction с opinions
chainguard/python~30-80 МБWolfi0-5fullProduction security focus

Выбор base image — дерево решений
Junior DE проектPostgres, MinIO, pandas, polars, sqlalchemy, airflow, dbt
default
python:3.13-slimGlibc-base, все wheels работают. ~150 МБ. Comfortable дебаг. Стандарт DE
нужен ОЧЕНЬ маленький размерНапример, ограничение IaaS-провайдера на размер образа, или edge-deployment
да
multi-stage + distroless или chainguardФинальный 50-80 МБ, дебаг через :debug вариант или ephemeral container
нет тяжёлых depsТолько requests, sqlalchemy, alembic, без pandas/scipy
можно
python:3.13-alpineРазмер 50 МБ. Но только если уверен, что все wheels есть для musl. Иначе — slim

Pin tag версии

python:3.13 — последний 3.13.x. python:3.13.0 — конкретно 3.13.0.

В production предпочитай specific:

FROM python:3.13.0-slim

Это гарантирует, что через год сборка даст идентичный результат. python:3.13-slim может через месяц стать 3.13.1 с потенциальными изменениями.

Самый строгий вариант — digest:

FROM python:3.13.0-slim@sha256:abc123...

Привязка к конкретному SHA256 образа. Никаких сюрпризов вообще. Цена — каждое обновление = ручная замена digest.

Для junior — pin’и до patch-версии (3.13.0-slim), digest можно опустить.


Multi-arch (ARM64 + x86_64)

С 2020 года Apple Silicon (M1/M2/M3/M4) — ARM64. Большинство облаков предлагают ARM64 (AWS Graviton, GCP T2A) с скидкой 20-40%. Образы должны работать на обоих.

Все официальные python-образы — multi-arch. docker pull python:3.13-slim на M1 mac автоматически потянет ARM64 версию.

Проблемы:

  • Не все wheels на PyPI собраны под ARM64. Некоторые экзотические пакеты падают на M1.
  • Если ты собираешь образ на x86 для деплоя на ARM (или наоборот), нужен docker buildx с --platform linux/arm64,linux/amd64.

Проверка:

docker inspect python:3.13-slim --format '{{.Architecture}}'

Покажет либо amd64, либо arm64 — зависит от хоста.


Реальный кейс выбора

DE-проект: Airflow + pandas + sqlalchemy + psycopg + pyarrow + duckdb. Что выбрать.

  • python:3.13-alpine — пробуем. pip install pyarrow крутится 15 минут — нет musl wheel в 2026 для pyarrow 15. Решение: отказываемся.
  • python:3.13-slimpip install ... за 40 секунд. Образ 280 МБ. Дебаг через bash. Берём.
  • distroless/python3 — финальный размер 150 МБ. Но дебаг сложнее, в команде junior’ы. Откладываем на потом.

Итоговый Dockerfile:

FROM python:3.13-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
    libpq5=15.* \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

RUN useradd -m -u 1000 app
COPY --chown=app:app . .
USER app

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

280 МБ, собирается за 50 секунд, удобный дебаг. Это про-junior baseline.


Попробуй сам

  1. Собери одно простое приложение (pip install pandas requests) на трёх образах:
    FROM python:3.13-slim
    RUN pip install pandas requests
    Замени FROM на python:3.13-alpine и python:3.13. Замерь размеры и время сборки. Сравни.
  2. На alpine попробуй pip install pyarrow — будь готов к 15-минутной сборке (или fail).
  3. Проверь архитектуру образа: docker inspect python:3.13-slim --format '{{.Architecture}}'. На M-маке — arm64, на x86 — amd64.
  4. Сравни CVE: trivy image python:3.13 vs trivy image python:3.13-slim vs trivy image python:3.13-alpine. Запиши количество HIGH/CRITICAL.
  5. Бонус: попробуй chainguard или distroless. Для distroless — multi-stage с builder.

Проверка знанийKnowledge check
Почему python:3.13-alpine — плохой выбор для Data Engineering проекта с pandas, numpy, pyarrow, и какие технические причины за этим стоят?
ОтветAnswer
Alpine Linux использует musl libc — альтернативный стандартный C-runtime, бинарно НЕсовместимый с glibc (стандартом на Debian/Ubuntu/RHEL). Python wheels на PyPI традиционно собираются под manylinux — стандарт, который требует glibc. Это значит: 1) Когда pip install pandas на python:3.13-alpine, pip ищет musllinux wheel. Для popular пакетов (pandas, numpy, polars) он есть — отлично, ставится за секунды. 2) Для менее popular пакетов musllinux wheel может отсутствовать. Тогда pip пытается собрать из исходников. Для C/C++/Fortran-зависимостей (pyarrow, scipy, ML-либы) это требует: - gcc, g++, gfortran, make - libc-dev, build-base, python3-dev - Часто часов CPU-времени 3) Образ распухает: 50 МБ alpine + 600 МБ build-tools = 700 МБ. Multi-stage помогает, но добавляет сложности. 4) Pyarrow в 2026 — самый болезненный пример. Wheels для musl выходят с задержкой и не для всех версий Python. Сборка с нуля = 20+ минут. Альтернатива — python:3.13-slim (Debian glibc): 150 МБ, все wheels работают «из коробки», pandas/numpy/pyarrow ставится за 30 секунд. Чуть больше размер, но в 10 раз меньше boilerplate. Когда alpine OK: маленькие сервисы без тяжёлых деп (FastAPI + sqlalchemy + asyncpg). Когда alpine плох: всё с pandas, numpy, sklearn, TensorFlow, pyarrow — то есть весь DE-стек. Правило: для DE — default python:3.13-slim, никогда alpine без проверки совместимости.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. Для DE-проекта с pandas, numpy, pyarrow какой base image использовать как DEFAULT?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5