Образ - це набір шарів, і кожна інструкція Dockerfile, що змінює файлову систему (RUN, COPY, ADD), створює новий шар. Розмір образу - сума шарів.
Історія шарів:
docker image history myapp:latest
IMAGE CREATED BY SIZE
a1b2c3d4e5f6 COPY . /var/www/html 48MB
<missing> RUN composer install --no-dev 62MB
<missing> RUN apt-get update && apt-get install ... 310MB
<missing> FROM php:8.5-fpm ...
Видно, яка інструкція скільки додала. --no-trunc показує повні команди.
Метадані образу:
docker image inspect myapp:latest
Змінні оточення, ENTRYPOINT/CMD, відкриті порти, мітки, архітектура (amd64/arm64), кількість шарів.
Що всередині файлової системи:
docker run --rm -it myapp:latest sh # зайти й подивитися
docker run --rm myapp:latest du -sh /var/www/html/* | sort -h
Інструмент dive показує вміст кожного шару і файли, які були додані в одному шарі й видалені в наступному (марнування місця).
Типові причини великих образів:
- кеш менеджерів пакетів:
apt-get installбезrm -rf /var/lib/apt/lists/*в тому самомуRUN; - інструменти збирання у фінальному образі: компілятори,
git,node_modulesдля збирання фронтенду - їх прибирає multi-stage build; - зайве в контексті:
.git, тести, локальні файли - потрібен.dockerignore; chown -Rокремою інструкцією - копія всіх файлів у новому шарі;- важкий базовий образ - повний Debian замість
slim.
Чому docker image ls і реальний розмір відрізняються: спільні шари базового образу зберігаються на диску один раз для всіх образів, що на ньому побудовані. docker system df -v показує, скільки займають шари насправді.
Розмір має значення: час завантаження при деплої й масштабуванні, місце в реєстрі, поверхня атаки (кожен зайвий пакет - потенційна вразливість).