← Назад к вопросам

Почему в Docker используется только JRE?

2.0 Middle🔥 211 комментариев
#Docker, Kubernetes и DevOps

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Почему в Docker используется JRE, а не JDK

Это отличный вопрос, который показывает понимание оптимизации образов. На самом деле, в современных Docker образах ситуация немного сложнее, чем просто JRE vs JDK.

1. Размер образа

Основная причина — размер:

  • JDK (Java Development Kit): 400-500 МБ (включает компилятор, tools, документацию)
  • JRE (Java Runtime Environment): 100-150 МБ (только для запуска)
# Старый подход — JRE образ
FROM openjdk:11-jre
WORKDIR /app
COPY app.jar .
CMD ["java", "-jar", "app.jar"]
# Итоговый размер: ~200 МБ

# Лучше — multi-stage build
FROM openjdk:11 as builder
WORKDIR /app
COPY . .
RUN ./gradlew build

FROM openjdk:11-jre
COPY --from=builder /app/build/libs/*.jar app.jar
CMD ["java", "-jar", "app.jar"]
# Итоговый размер: ~150 МБ (без исходников)

2. Отсутствие необходимости в JDK

В Docker контейнере приложение уже скомпилировано (JAR файл):

  • Компилятор javac не нужен
  • Tools для разработки не нужны
  • Достаточно JVM для выполнения bytecode
// Это уже скомпилировано в .class файлы внутри JAR
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello");
    }
}

3. Современный подход — Alpine и Distroless

На самом деле, в production чаще используют ещё более лёгкие образы:

Alpine Linux (очень мал)

FROM openjdk:11-jre-alpine
WORKDIR /app
COPY app.jar .
CMD ["java", "-jar", "app.jar"]
# Размер: ~70-80 МБ

Google Distroless (минимальный набор)

FROM eclipse-temurin:11-jre as runtime
FROM gcr.io/distroless/java11-debian11
COPY --from=runtime /opt/java/openjdk /opt/java/openjdk
COPY app.jar /app/
ENTRYPOINT ["/opt/java/openjdk/bin/java", "-jar", "/app/app.jar"]
# Размер: ~40-50 МБ, без оболочки ОС

4. Безопасность

Меньший образ = меньше потенциальных уязвимостей:

  • Нет компилятора → нет уязвимостей в javac
  • Нет лишних утилит → меньше surface area для атак
  • Distroless вообще не содержит shell
# Distroless образ не имеет shell
# Невозможно выполнить: docker exec -it container /bin/bash
# Это дополнительный уровень безопасности

5. Современная реальность — custom JRE

С Java 9+ появился jlink — инструмент для создания custom Runtime:

# Этап 1: сборка
FROM openjdk:11 as builder
WORKDIR /app
COPY . .
RUN ./mvn clean package

# Этап 2: создание custom JRE (только нужные модули)
RUN jlink --add-modules java.base,java.logging,java.sql \
    --compress=2 \
    --output /custom-jre

# Этап 3: runtime
FROM ubuntu:20.04
COPY --from=builder /custom-jre /usr/local/java
COPY --from=builder /app/target/app.jar /app/
ENV PATH="/usr/local/java/bin:$PATH"
CMD ["java", "-jar", "/app/app.jar"]
# Размер: 30-40 МБ (только нужные модули)

6. Лучшие практики Docker для Java

Multi-stage build (рекомендуется)

# Этап 1: сборка с полным JDK
FROM maven:3.8-openjdk-11 as builder
WORKDIR /build
COPY . .
RUN mvn clean package -DskipTests

# Этап 2: runtime с JRE
FROM openjdk:11-jre-alpine
WORKDIR /app
COPY --from=builder /build/target/app.jar .
EXPOSE 8080
CMD ["java", "-Xmx512m", "-jar", "app.jar"]

Health check

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
  CMD curl -f http://localhost:8080/health || exit 1

7. Когда нужен JDK в контейнере

Нечасто, но есть сценарии:

  • Development контейнеры: IDE, компиляция на лету
  • Hot reload: Динамическая загрузка новых классов
  • REPL окружение: Интерактивная работа
# Development образ
FROM openjdk:11
RUN apt-get update && apt-get install -y git maven
WORKDIR /workspace
# Разработчик может компилировать и запускать

Заключение

Итоговая иерархия образов по размеру:

  1. Distroless (~40 МБ) — максимальная безопасность, минимальный функционал
  2. Alpine (~70 МБ) — хороший баланс безопасности и функционала
  3. JRE (~150 МБ) — стандартный выбор для production
  4. JDK (~400 МБ) — только для разработки и сборки

Выбор зависит от требований к безопасности, размеру и производительности. В большинстве случаев Alpine + JRE — это оптимальное решение.