← Назад к вопросам
Почему в 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
# Разработчик может компилировать и запускать
Заключение
Итоговая иерархия образов по размеру:
- Distroless (~40 МБ) — максимальная безопасность, минимальный функционал
- Alpine (~70 МБ) — хороший баланс безопасности и функционала
- JRE (~150 МБ) — стандартный выбор для production
- JDK (~400 МБ) — только для разработки и сборки
Выбор зависит от требований к безопасности, размеру и производительности. В большинстве случаев Alpine + JRE — это оптимальное решение.