Docker 与 Java:从 A 到 Z 的应用程序容器化

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么 Docker 对 Java 开发者很重要?



现代 Java 开发很少能离开容器化。Docker 允许将应用程序及其所有依赖项、JVM 和配置打包到一个隔离的容器中。这解决了“在我机器上能运行”的问题,并简化了 CI/CD。在本文中,我们将分析完整的流程:从安装 Docker 到优化生产环境镜像。



1. Java 的 Docker 基础



1.1 什么是 Docker,为什么 Java 项目需要它?



Docker 是一个用于在容器中创建、交付和运行应用程序的平台。对于 Java 来说,这尤其重要:

  • JVM 版本隔离 — 可以在同一主机上为一个服务使用 Java 11,为另一个服务使用 Java 17。
  • 可重现性 — 镜像包含精确版本的 JDK、库和系统工具。
  • 可扩展性 — 通过 Kubernetes 或 Docker Swarm 轻松运行多个实例。


1.2 安装 Docker



首先,安装 Docker Desktop(Windows/Mac)或 Docker Engine(Linux)。验证安装:



docker --versiondocker info


2. 为 Java 应用程序创建 Dockerfile



考虑一个简单的 Spring Boot 应用程序。在项目根目录下创建一个 Dockerfile 文件。



2.1 基础 Dockerfile



# 使用官方 OpenJDK 镜像FROM openjdk:17-jdk-alpine

# 设置工作目录WORKDIR /app

# 复制 JAR 文件COPY target/myapp.jar app.jar

# 开放端口EXPOSE 8080

# 启动命令ENTRYPOINT ["java", "-jar", "app.jar"]


2.2 构建并运行容器



# 构建镜像docker build -t my-java-app .

# 运行容器docker run -p 8080:8080 my-java-app


运行后,应用程序可通过 http://localhost:8080 访问。



3. 优化 Java 的 Docker 镜像



大型镜像会减慢部署速度。让我们探讨关键优化技术。



3.1 多阶段构建



允许将构建阶段与运行阶段分开。最终镜像中只包含 JAR,不包含 Maven/Gradle 和源代码。



# 构建阶段FROM maven:3.8.5-openjdk-17 AS buildWORKDIR /appCOPY pom.xml .RUN mvn dependency:go-offlineCOPY src ./srcRUN mvn package -DskipTests

# 运行阶段FROM openjdk:17-jdk-alpineWORKDIR /appCOPY --from=build /app/target/myapp.jar app.jarEXPOSE 8080ENTRYPOINT ["java", "-jar", "app.jar"]


3.2 层优化



Docker 会缓存层。将数据复制分开:先复制依赖项(很少更改),再复制代码(经常更改)。



FROM maven:3.8.5-openjdk-17 AS buildWORKDIR /app# 仅复制 POM 并下载依赖项COPY pom.xml .RUN mvn dependency:go-offline# 复制源代码并构建COPY src ./srcRUN mvn package -DskipTests

FROM openjdk:17-jdk-alpineWORKDIR /appCOPY --from=build /app/target/*.jar app.jarEXPOSE 8080ENTRYPOINT ["java", "-jar", "app.jar"]


3.3 使用 jlink 创建最小 JRE



如果您使用 Java 9+,可以创建仅包含所需模块的自定义 JRE。



FROM openjdk:17-slim AS jre-buildRUN jlink --add-modules java.base,java.logging,java.sql \          --output /jre \          --strip-debug \          --no-man-pages \          --no-header-files

FROM alpine:latestCOPY --from=jre-build /jre /jreCOPY target/app.jar /app.jarENTRYPOINT ["/jre/bin/java", "-jar", "/app.jar"]


这样的镜像可能小于 50 MB,而不是 300+ MB。



4. 用于 Java 微服务的 Docker Compose



如果您有多个服务(例如 Spring Boot + PostgreSQL),请使用 docker-compose.yml。



4.1 示例

博客

书籍推荐