Java Docker 部署
把 Java 服务装进容器:镜像分层、内存参数与健康检查基本实践。
#type / howto
#status / growing
#tech / dev
#resource / java
[!info] 关联笔记
Java Docker 部署
目标
- 多阶段构建产出运行镜像
- 以非 root 运行
- 正确处理容器内存与退出信号
- 提供健康检查端点配合编排
这个场景为什么出现
部署单元从“机器上的 jar”变成镜像。JVM 与 cgroup 内存、信号、只读层需要额外纪律。
[!abstract] 一句话理解 构建阶段产出 jar,运行阶段用精简 JRE 镜像启动;配置由环境注入,并确保 SIGTERM 触发优雅关闭。
最小可运行示例
场景:Dockerfile 概念模板
# 概念示例(按项目调整)
FROM eclipse-temurin:21-jdk AS build
WORKDIR /src
COPY . .
RUN ./mvnw -q -DskipTests package
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=build /src/target/app.jar /app/app.jar
USER 10001
ENV JAVA_TOOL_OPTIONS="-XX:MaxRAMPercentage=75.0"
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]
本地示意:
# docker build -t shop-order:dev .
# docker run --rm -p 8080:8080 -e APP_PORT=8080 shop-order:dev
结合场景再看三个关注点
- JDK 构建 / JRE 运行分层。
- MaxRAMPercentage 适应容器内存。
- PID1/信号:确保 java 能收到 SIGTERM(注意 shell 包装)。
核心步骤与准确模型
- 可复现构建
- 最小运行镜像
- 配置外置
- 健康检查与探针
- 资源 requests/limits
工程实践
- 固定基础镜像摘要。
- 扫描 CVE。
- 只读根文件系统(若可行)。
- 与优雅关闭联调。
本节总结
- 多阶段镜像
- 容器内存感知
- 信号与配置
自测题
- 为什么运行镜像不必含 jdk 编译器?
- shell 形式 ENTRYPOINT 的信号风险?
参考答案
- 减小攻击面与体积,运行只需 JRE。
- 信号可能被 shell 吞/不转发,影响优雅关闭。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| Eclipse Temurin images | 镜像 | 基础镜像 |
| Container support in Java | 官方博客线索 | 容器感知 |