Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про Docker: Docker, Dockerfile, image layers, container size, build cache

Почему удаление файлов в Dockerfile не уменьшает итоговый размер образа?

Вопрос проверяет понимание устройства слоёв Docker-образов и того, как операции в Dockerfile влияют на итоговый размер контейнера.

Короткий ответ

Docker-образ состоит из слоёв, каждый слой — это результат выполнения одной инструкции в Dockerfile. Удаление файла в одном слое не удаляет его из предыдущих слоёв, так как слои неизменяемы. Файл физически остаётся в истории слоёв, просто в последнем слое он помечается как удалённый. Чтобы уменьшить размер, нужно объединять операции в одной инструкции RUN, используя цепочки команд, или применять multi-stage сборку.

Длинный ответ

Docker-образ — это набор неизменяемых слоёв (layers), каждый из которых соответствует одной инструкции в Dockerfile. Когда вы выполняете команды, такие как RUN, COPY или ADD, Docker создаёт новый слой поверх предыдущих. Это обеспечивает кэширование и повторное использование слоёв, но имеет важное следствие для управления размером.

Почему удаление не уменьшает размер

Представьте, что в Dockerfile вы сначала копируете большой архив, а затем удаляете его:

COPY big-archive.tar.gz /app/
RUN tar -xzf /app/big-archive.tar.gz -C /app
RUN rm /app/big-archive.tar.gz

Инструкция COPY создаёт слой, содержащий файл big-archive.tar.gz. Инструкция RUN rm создаёт новый слой, в котором этот файл удалён. Однако слой с COPY остаётся в истории образа и продолжает занимать место. Файл не удаляется физически из образа; он просто становится недоступным в конечной файловой системе, так как последний слой "перекрывает" его удалением.

Как правильно уменьшить размер

Чтобы избежать накопления ненужных данных, нужно минимизировать количество слоёв и удалять временные файлы в той же инструкции RUN, в которой они создаются. Это можно сделать, объединяя команды с помощью && и обратной косой черты для читаемости:

RUN curl -O https://example.com/big-archive.tar.gz \
    && tar -xzf big-archive.tar.gz \
    && rm big-archive.tar.gz

Все три операции (скачивание, распаковка, удаление) выполняются в рамках одного слоя. Временный архив не сохраняется в отдельном слое, поэтому итоговый размер образа будет меньше.

Использование Multi-stage сборки

Для сложных сценариев, например, когда нужно скомпилировать приложение, а затем перенести только результат, используйте multi-stage сборку. Это позволяет создать временный образ для сборки, а в финальный образ скопировать только необходимые артефакты, исключив промежуточные зависимости.

# Этап сборки
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .

# Финальный этап
FROM alpine:latest
COPY --from=builder /app/myapp /usr/local/bin/
CMD ["/usr/local/bin/myapp"]

В этом примере исходный код, компилятор Go и все промежуточные файлы остаются в образе builder, который не попадает в финальный образ. Копируется только исполняемый файл myapp, что значительно сокращает размер.

Вывод: Удаление файлов в отдельном слое Dockerfile неэффективно для уменьшения размера образа. Чтобы оптимизировать размер, объединяйте связанные команды в одной инструкции RUN и используйте multi-stage сборку для исключения ненужных артефактов сборки из финального образа.

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • Docker

    Docker

Ключевые слова

#Docker

#Dockerfile

#image layers

#container size

#build cache

Подпишись на React Developer в телеграм