Как Docker помогает уменьшить размер образа приложения?

«Как Docker помогает уменьшить размер образа приложения?» — вопрос из категории DevOps, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Docker оптимизирует размер образов за счет слоистой файловой системы (UnionFS) и специальных практик написания Dockerfile.

Основные механизмы и best practices:

  1. Многоэтапная сборка (Multi-stage build): Позволяет использовать один этап для сборки приложения, а другой — для финального образа, копируя только необходимые артефакты.

    # Этап сборки
    FROM maven:3.8-openjdk-17 AS builder
    WORKDIR /app
    COPY . .
    RUN mvn clean package -DskipTests
    
    # Финальный этап
    FROM openjdk:17-jdk-slim
    WORKDIR /app
    COPY --from=builder /app/target/my-app.jar ./app.jar # Копируем только JAR
    CMD ["java", "-jar", "app.jar"]
  2. Использование минимальных базовых образов: Выбор -slim или -alpine версий (например, openjdk:17-jdk-slim, node:18-alpine).

  3. Объединение команд RUN и очистка кэша: Уменьшает количество слоев и удаляет временные файлы.

    RUN apt-get update && apt-get install -y package 
        && rm -rf /var/lib/apt/lists/*  # Очистка кэша apt
  4. Игнорирование ненужных файлов: Использование .dockerignore для исключения из контекста сборки файлов (.git, node_modules, логов, временных файлов).

  5. Переиспользование слоев: Общие базовые слои (ОС, runtime) кэшируются и используются разными образами, экономя дисковое пространство.