🐳 Начало «диеты» образов Docker: Разбираем родословную с помощью docker history
Бывает, что вы запускаете всего одно легкое приложение, но при проверке обнаруживаете, что размер образа превышает 1 ГБ. Возникает вопрос: «Что я такого добавил?» В такие моменты необходимо разобраться в «родословной» образа.

«Что же ты съел, чтобы так вырасти?»
Образ Docker подобен многослойной луковице. Команда docker history — это рентген, который позволяет снять каждый слой и найти «виновника» его разрастания.
Её базовое использование очень просто:
# Базовое использование
docker history [опции] <имя_образа:тег>
# Пример: проверка истории моего приложения
docker history my-app:latest
При выполнении команды отображается полная история образа, начиная с самого нового слоя и до базового образа, в обратном хронологическом порядке.
IMAGE CREATED CREATED BY SIZE
a6215f271958 5 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
<missing> 7 weeks ago /bin/sh -c #(nop) ADD file:f28242cf608f6... 7.81MB
Внимательно посмотрите на столбец SIZE. Если там, где должно быть 0B, указаны сотни мегабайт, значит, это ваш кандидат на «диету». С опытом вы быстро научитесь чувствовать, где «пахнет неладным».
**💡 Полезный совет:
--no-trunc** `По умолчанию вывод команды обрезается, если она слишком длинная. Добавление опции
--no-truncпозволяет увидеть команду целиком без обрезки, что крайне важно для точного анализа.
docker history --no-trunc my-app:latest
Практический пример: «Виновником оказался chown»
Позвольте рассказать реальную историю из моего опыта. Я собирал проект размером 150 МБ, но образ в итоге весил более 300 МБ. Виновником оказались всего две, казалось бы, безобидные строки в Dockerfile.
[Неэффективный метод: создание двух слоев]
# 1. Сначала копируем файлы (по умолчанию копируются с правами root)
COPY . .
# 2. Изменяем владельца для безопасности (выполняется отдельной командой)
RUN chown -R appuser:appgroup /app
После сборки и проверки с помощью docker history я получил следующий результат:
IMAGE CREATED BY SIZE
<layer_id_2> /bin/sh -c chown -R appuser:appgroup /app 150MB <-- (Проблемное место!)
<layer_id_1> /bin/sh -c #(nop) COPY dir:abc in /app 150MB
Здесь проявляется коварство слоев Docker. На первом шаге, когда копируется файл размером 150 МБ, создается один слой. Но когда на втором шаге выполняется chown, Docker «говорит»: «Ой, информация о файле (владелец) изменилась? Тогда нужно создать еще один слой с новым состоянием!» — и копирует те же 150 МБ, создавая новый слой поверх существующего.
В итоге, одно и то же содержимое, но с разными правами владения, было сохранено дважды, что удвоило размер образа.
Решение: «диета» в одну строку!
Решение простое: достаточно указать права владения сразу при копировании, объединив таким образом создание слоев в один.
[Эффективный метод: создание одного слоя]
# Копирование и одновременное указание прав владения!
COPY --chown=appuser:appgroup . .
Если изменить Dockerfile таким образом и снова выполнить docker history, результат будет впечатляющим.
IMAGE CREATED BY SIZE
<layer_id_1> /bin/sh -c #(nop) COPY --chown=appuser... dir:abc 150MB
Видите? Создан всего один слой, и размер образа снова стал «стройным» — 150 МБ. Просто объединив две команды в одну, мы сократили размер вдвое.
Вывод: Всегда проверяйте «историю» после сборки!
Не забывайте: образ Docker — это один слой на каждую команду.
Как вы тестируете код после написания, так и после сборки образа возьмите за привычку запускать docker history --no-trunc. Вопросы вроде «Почему этот apt-get так много весит?» или «Зачем этот слой был разделен?» будут нанизываться один за другим, и незаметно для себя вы построите очень легкую и эффективную систему.
Ведь ненужные слои — враги вашей системы!
Было полезно? Если да, поставьте лайк!
Читайте также связанные статьи.
Связанные статьи
Полное руководство по общей памяти Docker: shm_size и ipc
Docker: Связь между контейнерами через порт хоста без общей сети
Комментариев нет.