22. Оптимизация образов
Размер Docker-образа влияет на скорость развёртывания, потребление дискового пространства и время загрузки. Оптимизация образов — важный навык для production-развёртываний.
Стратегии уменьшения размера
Заголовок раздела «Стратегии уменьшения размера»1. Выбор минимального базового образа
Заголовок раздела «1. Выбор минимального базового образа»# Сравнение базовых образов Node.js:FROM node:20 # 1.1 GB — полный DebianFROM node:20-slim # 240 MB — облегчённый DebianFROM node:20-alpine # 130 MB — Alpine LinuxFROM node:20-bookworm-slim # 240 MB — Debian Bookworm slim
# Для Go и других компилируемых языков:FROM scratch # 0 MB — пустой образFROM gcr.io/distroless/static # ~1 MB — только CA certsFROM gcr.io/distroless/nodejs20 # ~100 MB — только Node.js runtime2. Multi-stage builds
Заголовок раздела «2. Multi-stage builds»# Этап сборки (всё необходимое для компиляции)FROM node:20-alpine AS builderWORKDIR /appCOPY package*.json ./RUN npm ciCOPY . .RUN npm run build
# Финальный образ (только результат)FROM node:20-alpine AS productionWORKDIR /appCOPY package*.json ./RUN npm ci --only=productionCOPY --from=builder /app/dist ./distCMD ["node", "dist/server.js"]3. Правильный .dockerignore
Заголовок раздела «3. Правильный .dockerignore»# .dockerignore — исключить из контекста сборкиnode_modules/npm-debug.log.git/.gitignore.env.env.**.test.js*.spec.tscoverage/.nyc_output/dist/build/docs/*.md.DS_Store.vscode/Dockerfile*docker-compose*4. Объединение RUN команд
Заголовок раздела «4. Объединение RUN команд»# ❌ Три слояRUN apt-get updateRUN apt-get install -y curl wget gitRUN rm -rf /var/lib/apt/lists/*
# ✅ Один слой, кеш apt удаляется в том же слоеRUN apt-get update && \ apt-get install -y --no-install-recommends \ curl \ wget \ && rm -rf /var/lib/apt/lists/*5. Использование —no-install-recommends
Заголовок раздела «5. Использование —no-install-recommends»# Только необходимые пакеты, без рекомендованныхRUN apt-get install -y --no-install-recommends curlRUN apk add --no-cache curl # Alpine: --no-cache вместо rm /var/cache/apkАнализ размера образа
Заголовок раздела «Анализ размера образа»# История слоёв с размерамиdocker history myapp:latest
# Инструмент dive для детального анализаdive myapp:latest# Показывает:# - размер каждого слоя# - изменения в файловой системе# - эффективность образа (% неизменённых файлов)
# Экспорт и анализ образаdocker save myapp | tar tv | sort -k5 -rn | head -20
# Сравнение размеровdocker images | grep myappЧеклист оптимизации
Заголовок раздела «Чеклист оптимизации»# 1. Alpine/distroless базовый образFROM node:20-alpine
# 2. Сначала зависимости (для кеша)COPY package*.json ./RUN npm ci --only=production && npm cache clean --force
# 3. Потом кодCOPY --chown=node:node . .
# 4. Непривилегированный пользовательUSER node
# 5. Конкретная версия образаFROM node:20.11.0-alpine3.19
# 6. Удалить временные файлы в том же слоеRUN apk add --no-cache --virtual .build-deps gcc musl-dev && \ npm rebuild bcrypt --build-from-source && \ apk del .build-depsИнструменты анализа
Заголовок раздела «Инструменты анализа»# Docker Scout (встроен в Docker Desktop)docker scout quickview myapp:latestdocker scout recommendations myapp:latest
# Trivy — сканирование уязвимостейtrivy image --severity HIGH,CRITICAL myapp:latest
# dive — анализ слоёвbrew install divedive myapp:latest