
本教程旨在解决在dockerfile中构建spring boot应用时,maven打包的jar文件无法正确更新或传递到最终镜像的问题。通过详细讲解docker多阶段构建的原理与实践,我们将展示如何高效地将构建环境与运行环境分离,从而生成更小、更安全的docker镜像,并确保jar文件在运行时阶段的可用性。
在将Java或Spring Boot应用程序容器化时,一个常见的需求是将编译好的JAR文件打包到Docker镜像中运行。然而,开发者有时会遇到这样的困惑:在Dockerfile中执行mvn package命令后,生成的JAR文件似乎并未如预期般更新,或者在最终的运行环境中无法找到。这通常发生在尝试将构建逻辑与运行时环境分离,但未能正确实现文件传递时。
传统的单阶段Docker构建方式,即将所有编译、打包和运行的步骤都放在一个Dockerfile中,往往会导致以下问题:
当用户尝试优化这一过程,例如在Dockerfile中定义多个FROM指令,但没有正确地将前一阶段的构建产物传递到后一阶段时,就会出现类似“JAR文件未更新”或“找不到JAR文件”的问题。
Docker多阶段构建(Multi-stage builds)是解决上述问题的高效且推荐的实践方式。其核心思想是将Docker镜像的构建过程分解为多个独立的阶段,每个阶段使用不同的基础镜像,并专注于特定的任务。
什么是多阶段构建? 多阶段构建允许你在一个Dockerfile中定义多个FROM指令。每个FROM指令都标志着一个新的构建阶段。你可以为每个阶段命名,并在后续阶段中引用这些命名阶段,以便复制它们产生的工件。
多阶段构建的优势:
我们将通过一个具体的Spring Boot项目示例,演示如何使用多阶段构建来生成一个高效的Docker镜像。
项目结构示例:
Demo └── src | ├── main | │ ├── java | │ └── com | │ └── App.java | │ | │ | └── test | ├──── Dockerfile ├──── pom.xml
逐步构建多阶段Dockerfile:
这个阶段负责编译Java源代码并使用Maven打包成JAR文件。我们使用一个包含JDK和Maven的基础镜像。
# Stage 1: Build the application # 使用Maven官方镜像作为构建阶段的基础 FROM maven:3.8-jdk-11 as builder # 设置工作目录,后续所有操作都将在此目录下进行 WORKDIR /app # 复制Maven项目文件:pom.xml # 这一步可以利用Docker层缓存,如果pom.xml没有变化,则无需重新下载依赖 COPY pom.xml . # 复制源代码目录 COPY src ./src # 执行Maven打包命令,生成JAR文件 # -DskipTests: 在构建Docker镜像时通常跳过测试,以加快构建速度。 # 测试通常在CI/CD流水线的其他阶段执行。 RUN mvn clean package -DskipTests
在这一阶段,Maven会在/app/target目录下生成一个JAR文件。这个JAR文件是我们需要传递给下一个运行阶段的工件。
这个阶段负责创建一个轻量级的运行时镜像,只包含JRE和我们上一步构建好的JAR文件。
# Stage 2: Create the final runtime image # 使用轻量级的OpenJDK JRE镜像作为运行阶段的基础,例如openjdk:11-jre-slim FROM openjdk:11-jre-slim # 设置工作目录 WORKDIR /app # 关键步骤:从前一个阶段(builder)复制JAR文件 # --from=builder: 指定从名为“builder”的阶段复制文件 # /app/target/*.jar: 源路径,表示从builder阶段的/app/target目录下复制所有以.jar结尾的文件 # app.jar: 目标路径,将复制的文件重命名为app.jar并放置在当前阶段的/app目录下 COPY --from=builder /app/target/*.jar app.jar # 定义容器启动时执行的命令,运行Spring Boot应用 ENTRYPOINT ["java", "-jar", "app.jar"]
COPY --from=builder /app/target/*.jar app.jar 是多阶段构建的核心。它指示Docker从名为builder的阶段中,将/app/target/路径下的所有JAR文件复制到当前阶段的/app/目录下,并将其重命名为app.jar。这样,最终的镜像就只包含了运行应用所需的最小组件。
将以上两个阶段合并,即可得到一个完整的、高效的Spring Boot应用多阶段Dockerfile:
# --- Stage 1: Build the application --- FROM maven:3.8-jdk-11 as builder WORKDIR /app COPY pom.xml . COPY src ./src RUN mvn clean package -DskipTests # --- Stage 2: Create the final runtime image --- FROM openjdk:11-jre-slim WORKDIR /app # Copy the JAR from the 'builder' stage COPY --from=builder /app/target/*.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"]
FROM maven:3.8-jdk-11 as builder WORKDIR /app COPY pom.xml . RUN mvn dependency:go-offline # 仅下载依赖 COPY src ./src RUN mvn clean package -DskipTests
通过采用Docker多阶段构建,我们能够优雅地解决在Dockerfile中构建Spring Boot应用时JAR文件传递和镜像臃肿的问题。这种方法不仅显著减小了最终Docker镜像的体积,提升了安全性,还优化了构建流程。理解并正确运用COPY --from指令是实现高效Java应用容器化的关键。遵循这些最佳实践,可以确保你的Spring Boot应用在Docker环境中稳定、高效地运行。
以上就是在Dockerfile中构建Spring Boot JAR文件:多阶段构建实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号