Java项目正确使用Docker需选轻量JRE基础镜像、规范Dockerfile(WORKDIR/COPY/CMD)、宿主机编译JAR、确保Main-Class声明、配置时区与编码。

Java 本身不“安装 Docker”,Docker 是独立于编程语言的操作系统级工具;你在 Java 开发中用 Docker,实际是把 Java 应用打包成镜像、用 Docker 运行它——关键在配置 Dockerfile 和构建流程,不是给 JDK 装个 Docker 插件。
Java 项目怎么写 Dockerfile 才能正确运行
核心是选对基础镜像、正确拷贝和启动 JAR。别用 openjdk:17-jdk-slim(含 javac,体积大且不必要),优先用 openjdk:17-jre-slim 或更小的 eclipse-temurin:17-jre-alpine。
常见错误:把 java -jar app.jar 写进 CMD 却没设好工作目录或没加 -Dfile.encoding=UTF-8,导致中文乱码或找不到配置文件。
- 用
WORKDIR /app统一路径,避免相对路径出错 -
COPY target/*.jar app.jar后,确认 JAR 包名和路径与mvn package输出一致 - 启动命令推荐:
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "app.jar"],显式指定编码和参数 - 如需 JVM 参数调优(比如堆内存),直接加到
CMD中,例如"-Xmx512m"
本地构建镜像时 mvn package 总失败?检查这几点
很多 Java 开发者卡在构建阶段:Docker 构建时执行 mvn package 报错,其实是因为镜像里缺 Maven、没配 settings.xml、或网络无法拉依赖。
立即学习“Java免费学习笔记(深入)”;
更合理做法是「宿主机编译,容器只运行」——即先在本地跑 mvn clean package,再 COPY 生成的 JAR 进镜像。这样快、可复现、不依赖容器内 Maven 环境。
- 若坚持多阶段构建(推荐用于 CI 场景),第一阶段用
maven:3.9-openjdk-17,第二阶段用eclipse-temurin:17-jre-jammy - 多阶段构建中,务必用
COPY --from=0 /app/target/*.jar /app.jar显式指定源路径 - 私有仓库依赖?把宿主机的
~/.m2/settings.xmlCOPY 进构建阶段,并挂载~/.m2/repository避免重复下载
docker run 启动后立即退出?Java 进程没前台运行
典型现象:docker run -d my-java-app 返回容器 ID,但 docker ps 看不到,docker logs 显示 “no main manifest attribute” 或空。本质是 Java 进程启动后立刻结束,Docker 认为容器完成任务而退出。
原因常有两个:JAR 包没 Main-Class 声明,或入口类抛了未捕获异常直接退出。
- 检查 MANIFEST.MF:
jar -tf target/app.jar | grep MANIFEST,再jar -xf target/app.jar META-INF/MANIFEST.MF && cat META-INF/MANIFEST.MF | grep "Main-Class" - Spring Boot 项目确保用了
spring-boot-maven-plugin,它会自动写 Main-Class - 非 Spring Boot 项目,需在
pom.xml中配置插件显式指定:com.example.Main - 临时调试可用
docker run -it my-java-app /bin/sh进容器手动执行java -jar app.jar看报错
FROM eclipse-temurin:17-jre-jammy WORKDIR /app COPY target/myapp-1.0.jar app.jar EXPOSE 8080 CMD ["java", "-Dfile.encoding=UTF-8", "-Xmx256m", "-jar", "app.jar"]
真正容易被忽略的点:Docker 默认不继承宿主机的时区和 locale,Java 应用可能日志时间错乱、SimpleDateFormat 解析失败。启动容器时加 -e TZ=Asia/Shanghai 和 -v /etc/localtime:/etc/localtime:ro 才算完整。









