Раздутый Docker-образ — это медленные сборки, долгие выкладки и лишняя площадь для атак. При этом ужать образ в несколько раз можно базовыми приёмами, без экзотики. Разберём, что даёт основной выигрыш в 2025 году и почему порядок строк в Dockerfile важнее, чем кажется.
Многоэтапная сборка: главный рычаг
Самый мощный приём — многоэтапная сборка (multi-stage build). Идея в том, чтобы разделить сборку и запуск. На одном этапе вы собираете приложение со всеми компиляторами, сборщиками и инструментами отладки. На финальный этап копируете только то, что нужно для запуска, и берёте за основу более лёгкий образ.
- Используйте полноценный образ для сборки и тестов.
- Для продакшена берите слим-образ только с рантаймом.
- В финальный образ переносите лишь готовые артефакты, а не весь хлам сборки.
Результат — образ без компиляторов и dev-зависимостей, который может быть в разы меньше и имеет меньшую площадь атаки.
Порядок строк решает судьбу кэша
Docker кэширует слои сверху вниз и сбрасывает кэш с того места, где что-то изменилось. Отсюда правило: располагайте инструкции от самых редко меняющихся к самым частым.
- Сначала установка зависимостей — она меняется реже всего.
- Потом копирование кода приложения — оно меняется чаще всего.
- В конце настройка рантайма.
Если скопировать весь код до установки зависимостей, любая правка строки кода будет сбрасывать кэш зависимостей и заставлять ставить их заново. Правильный порядок экономит минуты на каждой сборке.
Кэш-маунты: ускорение без раздувания слоёв
В BuildKit есть кэш-маунты, которые кэшируют отдельные операции, не записывая их в слои образа. Например, кэш npm или apt живёт между сборками, но не утяжеляет итоговый образ. В типичном Node.js-приложении кэширование сокращает время сборки до 70%. Кэш-маунты и параллельная сборка требуют включённого BuildKit — это Docker версии 23.0 и выше или переменная DOCKER_BUILDKIT равная единице.
Выбор базового образа
Базовый образ задаёт стартовый вес и площадь атаки. На поздних этапах разработки приложению уже не нужны компиляторы и отладчики, поэтому для финального этапа берут минимальный образ с минимумом зависимостей. Это снижает и размер, и риск уязвимостей: чего нет в образе, то и нельзя проэксплуатировать.
Параллелизм этапов
Многоэтапная сборка не только уменьшает образ, но и ускоряет сам процесс: независимые этапы BuildKit может выполнять параллельно. Если разнести подготовку зависимостей и сборку фронтенда по разным этапам, они посчитаются одновременно, а не одна за другой.
Короткий чек-лист
Чтобы не держать всё в голове, пройдитесь по списку:
- Разделите Dockerfile на этап сборки и лёгкий этап запуска.
- Поставьте установку зависимостей до копирования кода.
- Включите BuildKit и добавьте кэш-маунты для пакетных менеджеров.
- Возьмите слим-образ для финального этапа.
Большую часть выигрыша дают два приёма: многоэтапная сборка и правильный порядок строк ради кэша. Начните с них — и образы станут меньше, а сборки заметно быстрее, без сложных инструментов и переписывания процесса.



Комментарии
Войдите, чтобы написать комментарий