Как оптимизировать Dockerfile
Вопрос
Образ приложения весит 1.5 ГБ и собирается 8 минут при любом изменении кода. Как будешь оптимизировать?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Порядок слоёв: сначала манифесты зависимостей и установка, код в конце
`.dockerignore`: убрать `.git`, `node_modules`, артефакты из контекста
Multi-stage: компиляторы и dev-зависимости только в стадии сборки
Базовый образ меньше: slim или distroless вместо полного
Чистка в той же инструкции (`rm -rf /var/lib/apt/lists/*`, `--no-cache-dir`)
BuildKit: `--mount=type=cache` для пакетных менеджеров, кеш в CI (`--cache-from`/`--cache-to`)
Что могут спросить следом
- Как посмотреть, какой слой самый тяжёлый?
- Как сохранить кеш сборки между запусками CI?
- Чем опасен alpine для Python?
Разбор
Сначала смотрю, что внутри: docker history и утилита dive покажут тяжёлые слои. Скорость: почти всегда виноват порядок, когда COPY . . стоит до установки зависимостей, и любая правка кода перезапускает npm ci или pip install. Переставляю: сначала манифесты и установка, код в конце. Добавляю .dockerignore, чтобы в контекст не уходили .git и node_modules. Размер: перехожу на multi-stage, в стадии сборки компиляторы, dev-зависимости и сборка, в финальную копирую только артефакт и продовые зависимости. Базу беру slim или distroless. Всё, что ставлю через apt, чищу в той же инструкции, pip ставлю с --no-cache-dir. В CI включаю кеш BuildKit: --mount=type=cache для пакетных менеджеров и экспорт кеша в реестр через --cache-to и --cache-from, иначе каждый раннер собирает с нуля. Типичный результат: сотни мегабайт вместо гигабайтов и пересборка за секунды, когда менялся только код.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.