Dockerfile: образы, слои и кэш сборки
Dockerfile — текстовый файл с инструкциями для сборки образа; каждая инструкция создаёт слой
Почему это важно: неправильный порядок инструкций делает сборку медленной; понимание слоёв экономит минуты на каждом CI-прогоне
Главная идея
слои кэшируются; если инструкция не изменилась, Docker берёт результат из кэша. Порядок инструкций критичен
Как это выглядит на практике
- FROM python:3.11-slim — выбираем базовый образ (минимальный Debian + Python).
- WORKDIR /app — устанавливаем рабочую директорию внутри контейнера.
- COPY requirements.txt . → RUN pip install -r requirements.txt — сначала зависимости (кэшируются).
- COPY . . — копируем код последним; изменения кода не инвалидируют кэш зависимостей.
- 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.
Термины урока
Связь с работой backend-разработчика
Хороший Dockerfile — быстрая CI-сборка. Разбейте установку зависимостей и копирование кода. Используйте .dockerignore. Выбирайте slim-образы. Это прямо влияет на время деплоя.
Мини-разбор реальной ситуации
Команда жалуется: docker build занимает 4 минуты. Причина: COPY . . стоит перед RUN pip install, поэтому при каждом изменении любого файла зависимости пересобираются с нуля. Перестановка двух строк сокращает время до 20 секунд при обычных изменениях кода.
Что запомнить
- Сначала COPY зависимостей, потом RUN install, потом COPY кода.
- Объединяй RUN-команды в один слой через &&.
- .dockerignore обязателен в каждом проекте.
Итог
Хорошо написанный Dockerfile — это инвестиция в скорость. Быстрая сборка = быстрый feedback = продуктивная команда.