Комментарий пользователя
Привет! У меня небольшой агент на Python. Нужно, чтобы образ был минимален, билд быстрый, а контейнер стартовал без задержек. Как это сделать правильно?
Ответ специалиста
Здравствуйте! Надежный паттерн — multi-stage build: в первом слое собираете зависимости (особенно нативные) в wheels, в финальном образе ставите только runtime и готовые wheel-файлы.
Базовый выбор — python:3.x-slim. Но есть нюансы: не держите инструменты сборки в финальном образе, создайте non-root пользователя и запускайте python -u чтобы логи не буферизовались.
Вот пример рабочего Dockerfile:
# builder
FROM python:3.11-slim AS builder
WORKDIR /app
COPY pyproject.toml poetry.lock /app/
RUN apt-get update && apt-get install -y build-essential gcc \
&& pip install --upgrade pip poetry \
&& poetry export -f requirements.txt --without-hashes -o reqs.txt \
&& pip wheel --wheel-dir /wheels -r reqs.txt
# runtime
FROM python:3.11-slim
WORKDIR /app
RUN useradd --create-home appuser
COPY --from=builder /wheels /wheels
COPY . /app
RUN pip install --no-index --find-links=/wheels -r /app/reqs.txt \
&& rm -rf /wheels /root/.cache/pip
USER appuser
ENTRYPOINT ["python", "-u", "main.py"]
Альтернативный вариант с использованием пакетного менеджера `uv`. На практике он сильно ускоряет работу с зависимостями:
# builder_uv
FROM python:3.11-slim AS builder_uv
WORKDIR /app
RUN apt-get update && apt-get install -y curl build-essential gcc
RUN curl -LsSf astral.sh | sh
RUN rm -rf /var/lib/apt/lists/*
# Предполагается наличие requirements.txt
COPY requirements.txt /app/
RUN uv pip install --system --no-cache-dir --compile --wheel-dir /wheels -r requirements.txt
# runtime_uv
FROM python:3.11-slim
WORKDIR /app
RUN useradd --create-home appuser
COPY --from=builder_uv /wheels /wheels
COPY . /app
RUN pip install --no-index --find-links=/wheels -r /app/requirements.txt \
&& rm -rf /wheels /root/.cache/pip
USER appuser
ENTRYPOINT ["python", "-u", "main.py"]
Если будете придерживаться такого подхода, то это уменьшит размер и ускорит холодный старт. Контейнер сразу запускается с уже собранными бинарными колесами.
Проверяйте размер через docker images и время старта, держите healthcheck, и в CI кэшируйте wheels/артефакты, чтобы не пересобирать все заново.
Надеемся, эти советы помогут вам в работе, а чтобы не пропустить новые материалы, лайфхаки и обновления из мира IT, подписывайтесь на рассылку и канал Академии Selectel.