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

Как работает Build в Docker?

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

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

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

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

Docker Build процесс

Build в Docker — это процесс создания образа из набора инструкций (Dockerfile). Понимание этого процесса критично для оптимизации размера образов, скорости сборки и безопасности.

Этапы Docker Build

1. Чтение и парсинг Dockerfile

# Dockerfile — это набор команд, которые выполняются последовательно
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]
  • FROM — базовый образ (base image)
  • WORKDIR — рабочая директория в контейнере
  • COPY — копирование файлов с хоста
  • RUN — выполнение команд
  • CMD — команда по умолчанию

2. Создание контекста сборки

# Docker читает файлы из директории сборки (build context)
docker build -t myapp:1.0 .

# Контекст — все файлы в текущей директории
# Они отправляются Docker демону для сборки

Для оптимизации используй .dockerignore:

.git
.gitignore
__pycache__
*.pyc
.env
node_modules
.pytest_cache

3. Выполнение инструкций слой за слоем

Шаг 1: FROM python:3.11-slim
---> Загрузить базовый образ (слой 1)

Шаг 2: WORKDIR /app
---> Создать слой (пустой, просто метаданные)

Шаг 3: COPY requirements.txt .
---> Создать новый слой с файлом requirements.txt

Шаг 4: RUN pip install -r requirements.txt
---> Создать новый слой с установленными пакетами

Шаг 5: COPY . .
---> Создать новый слой с исходным кодом

Шаг 6: CMD ["python", "app.py"]
---> Метаданные (какую команду запускать)

Кэширование слоёв

Каждый слой кэшируется. Это ускоряет повторные сборки:

# Плохо: изменение исходного кода инвалидирует кэш для pip install
FROM python:3.11-slim
WORKDIR /app
COPY . .                          # Слой 1: весь исходный код
RUN pip install -r requirements.txt  # Слой 2: переустанавливается при каждом изменении

# Хорошо: разделить зависимости и код
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .           # Слой 1: только зависимости
RUN pip install -r requirements.txt  # Слой 2: кэшируется, пока requirements.txt не изменится
COPY . .                          # Слой 3: исходный код (часто меняется)

Как работает кэширование:

# Первая сборка (без кэша)
$ docker build -t app:1.0 .
Step 1/6 : FROM python:3.11-slim
---> ef123456 (загрузить базовый образ)
Step 3/6 : COPY requirements.txt .
---> ab789012 (новый слой, кэшировать)
Step 4/6 : RUN pip install...
---> cd345678 (новый слой, кэшировать)

# Вторая сборка (код изменился, requirements.txt нет)
$ docker build -t app:1.0 .
Step 1/6 : FROM python:3.11-slim
---> ef123456 (из кэша, совпадает)
Step 3/6 : COPY requirements.txt .
---> ab789012 (из кэша, совпадает)
Step 4/6 : RUN pip install...
---> cd345678 (из кэша, совпадает!)
Step 5/6 : COPY . .
---> xy999999 (новый слой, код изменился)

Многоэтапная сборка (Multi-stage Build)

Уменьшить размер образа, убрав инструменты сборки:

# Этап 1: Builder (содержит все инструменты)
FROM python:3.11 as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt  # Установить в ~/.local

# Этап 2: Runtime (только необходимое)
FROM python:3.11-slim
WORKDIR /app

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

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

Размер образов:

  • Образ с builder + runtime: ~900 MB
  • Образ только runtime: ~150 MB (84% меньше!)

Optimize Docker Build в Python

# Оптимальный Dockerfile для Python приложения
FROM python:3.11-slim

# 1. Установить переменные окружения
ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    PIP_NO_CACHE_DIR=1 \
    PIP_DISABLE_PIP_VERSION_CHECK=1

# 2. Установить системные зависимости (если нужны)
RUN apt-get update && apt-get install -y --no-install-recommends \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# 3. Создать непривилегированного пользователя
RUN useradd -m -u 1000 appuser

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

# 5. Копировать зависимости (рано, для кэша)
COPY requirements.txt .
RUN pip install -r requirements.txt

# 6. Копировать приложение
COPY --chown=appuser:appuser . .

# 7. Переключиться на непривилегированного пользователя
USER appuser

# 8. Запустить приложение
CMD ["python", "app.py"]

Команды build

# Базовая сборка
docker build -t myapp:1.0 .

# С тегами
docker build -t myapp:latest -t myapp:1.0 .

# С аргументами сборки
docker build --build-arg PYTHON_VERSION=3.11 -t myapp:1.0 .

# Без кэша (пересобрать всё)
docker build --no-cache -t myapp:1.0 .

# С дополнительными контекстами
docker build --build-context credentials=/path/to/creds -t myapp:1.0 .

# Платформа (для cross-platform)
docker build --platform linux/amd64 -t myapp:1.0 .

Инспектирование образа

# Размер образа
docker images myapp:1.0

# История слоёв
docker history myapp:1.0

# Детали образа
docker inspect myapp:1.0

# Запустить контейнер и посмотреть слои
docker run -it myapp:1.0 /bin/bash

Процесс сборки в Docker демоне

Клиент (docker build)        Docker Daemon
    |
    |----> Отправить контекст (TAR архив)
    |                           |
    |                           (Прочитать Dockerfile)
    |                           (Выполнить инструкции)
    |                           (Создать слои)
    |                           (Построить образ)
    |                           (Оптимизировать)
    |<----- Результат: образ

Безопасность при сборке

# Использовать официальные базовые образы
FROM python:3.11-slim  # ✓ Безопасно
FROM python  # ✗ Может быть небезопасным (latest)

# Не хранить секреты в образе
RUN curl https://api.example.com/secret.txt  # ✗ Плохо

# Использовать BuildKit secrets
RUN --mount=type=secret,id=api_key echo $API_KEY

Build в Docker — это мощный инструмент, который требует понимания кэширования слоёв и оптимизации для эффективной разработки.