← Назад к вопросам

Какие знаешь основные этапы написания Dockerfile?

1.3 Junior🔥 161 комментариев
#DevOps и инфраструктура

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Основные этапы написания Dockerfile

Dockerfile — это набор инструкций для создания Docker образа. Это критически важный навык для Python разработчика в современных реалиях. Рассмотрю полный процесс написания правильного Dockerfile.

1. Выбор базового образа (FROM)

Базовый образ — фундамент контейнера

# НЕПРАВИЛЬНО — слишком тяжёлый
FROM ubuntu:22.04

# ПРАВИЛЬНО для Python
FROM python:3.11-slim

# АЛЬТЕРНАТИВА — минимальный
FROM python:3.11-alpine

# Pinning версии ВАЖЕН для воспроизводимости
FROM python:3.11.8-slim-bullseye

Сравнение базовых образов:

ОбразРазмерUse Case
ubuntu:22.0477 MBПолная ОС, редко нужно
python:3.11-slim126 MBОптимум для приложений
python:3.11-alpine50 MBМинимальный, есть проблемы с некоторыми пакетами
python:3.111 GBПолный образ со всем, не рекомендуется

2. Установка рабочей директории (WORKDIR)

Организация структуры контейнера

# Устанавливаем рабочую директорию
WORKDIR /app

# Все команды далее выполняются в /app
RUN pwd  # выведет /app
COPY . .  # копирует в /app

3. Копирование файлов (COPY и ADD)

Copy — более простой и предпочтительный

# Копируем requirements в контейнер
COPY requirements.txt .

# Копируем весь исходный код
COPY . .

# ADD редко используется (для архивов)
ADD https://example.com/file.tar.gz .

4. Установка зависимостей (RUN)

Оптимизация: минимизация слоёв

# НЕПРАВИЛЬНО — много слоёв
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y git

# ПРАВИЛЬНО — один слой
RUN apt-get update && apt-get install -y \
    curl \
    git \
    && rm -rf /var/lib/apt/lists/*

Установка Python зависимостей

# Обновляем pip (важно!)
RUN pip install --upgrade pip

# Устанавливаем зависимости
RUN pip install --no-cache-dir -r requirements.txt

# --no-cache-dir уменьшает размер образа

5. Expose портов (EXPOSE)

Документирование портов

# EXPOSE не публикует порты, только документирует
EXPOSE 8000 5432

# При запуске используешь -p для маппинга
# docker run -p 8000:8000 my-app

6. Установка переменных окружения (ENV и ARG)

ENV — доступны в контейнере

ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV APP_HOME=/app

ARG — только во время сборки

ARG PYTHON_VERSION=3.11
FROM python:${PYTHON_VERSION}-slim

# Использование: docker build --build-arg PYTHON_VERSION=3.12

7. Точка входа (ENTRYPOINT и CMD)

ENTRYPOINT — основная команда

# Shell форма (не рекомендуется)
ENTRYPOINT python app.py

# JSON форма (рекомендуется)
ENTRYPOINT ["python", "-m", "uvicorn", "main:app"]

CMD — параметры по умолчанию

ENTRYPOINT ["python", "app.py"]
CMD ["--host", "0.0.0.0", "--port", "8000"]

# Можно переопределить при запуске
# docker run my-app --host localhost --port 9000

8. Multi-stage build (оптимизация размера)

Полный пример с несколькими этапами

# Stage 1: Builder
FROM python:3.11-slim AS builder

WORKDIR /build
COPY requirements.txt .

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

# Stage 2: Runtime (финальный образ)
FROM python:3.11-slim

WORKDIR /app

# Копируем только установленные пакеты из builder
COPY --from=builder /root/.local /root/.local

# Копируем исходный код
COPY . .

ENV PATH=/root/.local/bin:$PATH

EXPOSE 8000

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

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

  • Финальный образ меньше (не содержит build tools)
  • Более безопасен (меньше потенциальных уязвимостей)

9. Полный пример Dockerfile для FastAPI приложения

# Build stage
FROM python:3.11-slim as builder

WORKDIR /build
COPY requirements.txt .

RUN pip install --upgrade pip && \
    pip install --user --no-cache-dir -r requirements.txt

# Runtime stage
FROM python:3.11-slim

WORKDIR /app

ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    PIP_NO_CACHE_DIR=1

# Копируем пакеты
COPY --from=builder /root/.local /root/.local

# Копируем код
COPY . .

ENV PATH=/root/.local/bin:$PATH

EXPOSE 8000

HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
    CMD curl -f http://localhost:8000/health || exit 1

ENTRYPOINT ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

10. HEALTHCHECK (для мониторинга)

Проверка здоровья контейнера

HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
    CMD curl -f http://localhost:8000/health || exit 1

# Параметры:
# --interval: интервал проверки (30s)
# --timeout: максимальное время ответа (10s)
# --start-period: время до первой проверки (5s)
# --retries: количество ошибок для unhealthy (3)

11. .dockerignore файл (оптимизация сборки)

Исключаем ненужные файлы

.git
.gitignore
__pycache__
*.pyc
*.pyo
.pytest_cache
.venv
venv
.env
.env.local
node_modules
build/
dist/
.coverage
.mypy_cache
.idea

12. Чек-лист оптимизации Dockerfile

  • Используй slim или alpine базовый образ
  • Пинн версии всех зависимостей
  • Минимизируй слои (RUN команды объединяй)
  • Используй multi-stage build для уменьшения размера
  • Порядок инструкций важен для кэширования
  • Используй .dockerignore для исключения файлов
  • Установи HEALTHCHECK для мониторинга
  • Логирование без буферизации (PYTHONUNBUFFERED=1)
  • Non-root пользователь для безопасности
  • Минимизируй размер образа (используй --no-cache-dir)

13. Построение и запуск

# Построить образ
docker build -t my-app:1.0 .

# С аргументами сборки
docker build --build-arg PYTHON_VERSION=3.12 -t my-app:latest .

# Запустить контейнер
docker run -p 8000:8000 my-app:1.0

# С переменными окружения
docker run -p 8000:8000 -e DEBUG=true my-app:1.0

# Проверить размер
docker images | grep my-app

Выводы

  • FROM — выбирай slim образы
  • COPY — копируй только нужное
  • RUN — объединяй команды в один слой
  • Multi-stage build — уменьшает финальный размер
  • HEALTHCHECK — добавляй для мониторинга
  • .dockerignore — исключай ненужные файлы
  • Пинн версии для воспроизводимости
  • Порядок инструкций влияет на кэширование образа
Какие знаешь основные этапы написания Dockerfile? | PrepBro