Чому розмір має значення: довше завантаження при деплої й масштабуванні, більше місця в реєстрі й на серверах, більше пакетів - більше потенційних вразливостей.
Як знайти, що займає місце:
docker image ls myapp # загальний розмір
docker history myapp:1.4.2 # розмір кожного шару й команда, що його створила
dive myapp:1.4.2 # інтерактивний перегляд шарів і файлів
dive показує вміст кожного шару, які файли додано, змінено чи «видалено» в ньому, і оцінює «втрачене» місце.
Типові причини великого образу:
1. Видалення в окремому шарі. Шар неможливо зменшити наступним шаром - видалений файл просто приховується, але лишається в образі:
# погано: 300 МБ кешу лишаться в першому шарі
RUN apt-get update && apt-get install -y build-essential
RUN apt-get purge -y build-essential && rm -rf /var/lib/apt/lists/*
# добре: встановлення й чистка в одному RUN
RUN apt-get update \
&& apt-get install -y --no-install-recommends libzip-dev \
&& rm -rf /var/lib/apt/lists/*
2. Інструменти збирання в фінальному образі - компілятори, -dev-пакети, Composer, Node.js. Ліки - multi-stage: збирати в одному етапі, копіювати лише результат у фінальний.
3. Залежності для розробки: composer install без --no-dev, node_modules після збирання фронтенду (у фінальний образ потрібен лише public/build).
4. Зайве в контексті збирання: .git, тести, локальні vendor і node_modules через COPY . . без .dockerignore.
5. Кеші пакетних менеджерів: кеш Composer, npm, apk, apt - чистити в тому самому RUN або використовувати cache mounts (RUN --mount=type=cache), що взагалі не потрапляють в образ.
6. Рекомендовані пакети: apt-get install без --no-install-recommends тягне багато непотрібного.
7. Великий базовий образ: повний Debian замість slim/Alpine, якщо застосунку не потрібна сумісність, яку дає повний образ.
Корисні звички для PHP-образу: composer install --no-dev --optimize-autoloader --no-scripts на етапі залежностей, розширення - через docker-php-ext-install з видаленням -dev-пакетів у тому самому шарі, фронтенд - окремим етапом на образі Node.
Межа оптимізації: зменшувати розмір має сенс, доки це не шкодить читабельності Dockerfile і швидкості налагодження.