Все ли инструкции в Dockerfile создают новый слой в образе?

«Все ли инструкции в Dockerfile создают новый слой в образе?» — вопрос из категории Docker, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет, не все. Только инструкции, которые добавляют или изменяют файловую систему образа, создают новый слой (read-write layer). Остальные инструкции создают метаданные или конфигурацию для конечного образа.

Инструкции, создающие слой:

  • RUN – выполняет команду и фиксирует изменения файловой системы.
  • COPY и ADD – добавляют файлы/директории из контекста сборки или из URL в образ.

Инструкции, НЕ создающие слой (создают метаданные):

  • LABEL, ENV, ARG – устанавливают метаданные и переменные окружения.
  • EXPOSE, VOLUME, WORKDIR – задают конфигурацию времени выполнения.
  • CMD, ENTRYPOINT, HEALTHCHECK – определяют команду по умолчанию и поведение контейнера.

Пример для наглядности:

FROM alpine:3.18
# Создает слой (добавляет пакеты и файлы)
RUN apk add --no-cache nginx && 
    mkdir -p /var/log/nginx
# Не создает слой, только метаданные
ENV NGINX_VERSION=1.24.0 
    NGINX_HOST=localhost
# Создает слой (копирует файлы)
COPY nginx.conf /etc/nginx/
# Не создает слой, только конфигурацию
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Практическое следствие: Для оптимизации размера образа критически важно минимизировать количество слоев, особенно от RUN, COPY, ADD. Я всегда объединяю связанные команды RUN в одну цепочку с && и обратным слэшем , а также стараюсь копировать файлы одним действием после установки всех зависимостей.