Перейти к содержимому

22. Оптимизация образов

Размер Docker-образа влияет на скорость развёртывания, потребление дискового пространства и время загрузки. Оптимизация образов — важный навык для production-развёртываний.

# Сравнение базовых образов Node.js:
FROM node:20 # 1.1 GB — полный Debian
FROM node:20-slim # 240 MB — облегчённый Debian
FROM node:20-alpine # 130 MB — Alpine Linux
FROM node:20-bookworm-slim # 240 MB — Debian Bookworm slim
# Для Go и других компилируемых языков:
FROM scratch # 0 MB — пустой образ
FROM gcr.io/distroless/static # ~1 MB — только CA certs
FROM gcr.io/distroless/nodejs20 # ~100 MB — только Node.js runtime
# Этап сборки (всё необходимое для компиляции)
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Финальный образ (только результат)
FROM node:20-alpine AS production
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/server.js"]
# .dockerignore — исключить из контекста сборки
node_modules/
npm-debug.log
.git/
.gitignore
.env
.env.*
*.test.js
*.spec.ts
coverage/
.nyc_output/
dist/
build/
docs/
*.md
.DS_Store
.vscode/
Dockerfile*
docker-compose*
# ❌ Три слоя
RUN apt-get update
RUN apt-get install -y curl wget git
RUN 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/*
# Только необходимые пакеты, без рекомендованных
RUN apt-get install -y --no-install-recommends curl
RUN 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:latest
docker scout recommendations myapp:latest
# Trivy — сканирование уязвимостей
trivy image --severity HIGH,CRITICAL myapp:latest
# dive — анализ слоёв
brew install dive
dive myapp:latest