Сколько слоев создаст Docker при объединении нескольких команд в Dockerfile
Что проверяют
Понимаете ли вы, что образ это стопка слоёв, и связываете ли это с кэшем сборки и размером результата. Вопрос простой, но по ответу видно, собирали ли вы образы сами или копировали чужой Dockerfile.
Как отвечать
Слой создаёт каждая инструкция, которая меняет файловую систему: RUN, COPY, ADD. Значит, объединение нескольких команд в одну через && даёт один слой вместо нескольких:
RUN apt-get update && apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*Инструкции, меняющие только метаданные (ENV, WORKDIR, USER, EXPOSE, LABEL, CMD, ENTRYPOINT), слоёв с данными не добавляют. FROM приносит слои базового образа.
Дальше объясните, зачем вообще объединяют:
- размер: слой хранит разницу, и удаление файла в следующем слое образ не уменьшает, файл остаётся лежать в нижнем;
- кэш: слои проверяются по порядку, и первая изменившаяся инструкция обнуляет кэш всего, что ниже;
- у драйвера overlay2 есть предел на число нижних слоёв, так что бесконечно их плодить нельзя.
Для Python отсюда следует правильный порядок: сначала копируется файл зависимостей и ставятся пакеты, и только потом копируется код. Иначе каждая правка строки пересобирает всё окружение.
Где спотыкаются
Говорят «каждая строка Dockerfile создаёт слой». Инструкции метаданных слой с данными не создают, и на уточняющий вопрос про ENV ответ разваливается.
Чистят кэш пакетного менеджера отдельной инструкцией RUN и удивляются, что образ не похудел. Удаление в верхнем слое только прячет файлы, вес остаётся.
Схлопывают весь Dockerfile в одну гигантскую инструкцию ради «одного слоя» и убивают кэш: любая правка пересобирает всё с нуля. Размер лучше сокращать многоступенчатой сборкой и тонким базовым образом, а не гонкой за минимальным числом слоёв.