Начальный ~20 мин чтения

Dockerfile: образы, слои и кэш сборки

Урок 2 из 6 в курсе Docker для разработчика

Dockerfile: образы, слои и кэш сборки

Dockerfile — текстовый файл с инструкциями для сборки образа; каждая инструкция создаёт слой

Почему это важно: неправильный порядок инструкций делает сборку медленной; понимание слоёв экономит минуты на каждом CI-прогоне

Главная идея

слои кэшируются; если инструкция не изменилась, Docker берёт результат из кэша. Порядок инструкций критичен

Как это выглядит на практике

  1. FROM python:3.11-slim — выбираем базовый образ (минимальный Debian + Python).
  2. WORKDIR /app — устанавливаем рабочую директорию внутри контейнера.
  3. COPY requirements.txt . → RUN pip install -r requirements.txt — сначала зависимости (кэшируются).
  4. COPY . . — копируем код последним; изменения кода не инвалидируют кэш зависимостей.
  5. CMD ["python", "app.py"] — команда по умолчанию при запуске контейнера.

Что происходит под капотом

  • Каждая инструкция RUN, COPY, ADD создаёт новый слой поверх предыдущего.
  • Слой — это diff файловой системы: только изменения относительно предыдущего слоя.
  • Cache invalidation: изменение любой инструкции инвалидирует кэш всех последующих слоёв.
  • docker build --no-cache принудительно пересобирает все слои.
  • .dockerignore работает как .gitignore: исключает файлы из контекста сборки (node_modules, .git).

Типичные ошибки и заблуждения

  • Ошибка: порядок инструкций не важен. COPY . . перед установкой зависимостей означает пересборку при каждом изменении кода.
  • Ошибка: RUN apt-get update и RUN apt-get install лучше разбить. Их нужно объединить в одну RUN, иначе apt-get update кэшируется отдельно.
  • Ошибка: FROM ubuntu — хорошая основа. Для продакшена используйте slim/alpine-образы; ubuntu слишком велик.
  • Ошибка: CMD и ENTRYPOINT одно и то же. ENTRYPOINT — основная команда, CMD — аргументы по умолчанию к ней.

Ключевые выводы

  • Порядок инструкций: сначала то, что меняется редко (зависимости), потом то, что часто (код).
  • Объединяйте RUN-команды через && чтобы уменьшить число слоёв.
  • .dockerignore обязателен: он ускоряет сборку и уменьшает образ.
  • Используйте конкретные теги версий: FROM node:20-slim, не FROM node:latest.

Термины урока

FROM: базовый образ, с которого начинается сборка.
RUN: выполняет команду и создаёт новый слой.
COPY: копирует файлы из контекста сборки в образ.
CMD: команда по умолчанию при запуске контейнера.
WORKDIR: устанавливает рабочую директорию для последующих инструкций.
Build cache: кэш слоёв; Docker переиспользует слои если инструкция и контекст не изменились.

Связь с работой backend-разработчика

Хороший Dockerfile — быстрая CI-сборка. Разбейте установку зависимостей и копирование кода. Используйте .dockerignore. Выбирайте slim-образы. Это прямо влияет на время деплоя.

Мини-разбор реальной ситуации

Команда жалуется: docker build занимает 4 минуты. Причина: COPY . . стоит перед RUN pip install, поэтому при каждом изменении любого файла зависимости пересобираются с нуля. Перестановка двух строк сокращает время до 20 секунд при обычных изменениях кода.

Что запомнить

  • Сначала COPY зависимостей, потом RUN install, потом COPY кода.
  • Объединяй RUN-команды в один слой через &&.
  • .dockerignore обязателен в каждом проекте.

Итог

Хорошо написанный Dockerfile — это инвестиция в скорость. Быстрая сборка = быстрый feedback = продуктивная команда.