您已经创建了一个 Spring Boot 应用程序。它在您的本地计算机上运行良好,现在您需要将该应用程序部署到其他地方。在某些平台上,您可以直接提交jar文件,它将被部署。在某些地方,您可以启动虚拟机,下载源代码,构建并运行它。但是,大多数时候您需要使用容器来部署应用程序。大多数时候,Docker 用于在容器中构建和运行镜像。此外,当您将 jar 文件上传到某些平台时,应用程序会在后台的容器内运行。
因此,在本博客中,我们将看到 3 种不同的方法来为给定的 Spring Boot 应用程序构建 Docker 映像。让我们开始吧:
为任何应用程序构建 Docker 映像的简单且不充分的方法是使用一个简单的 Dockerfile,它将 jar 文件复制到映像中并使用 java -jar 命令运行它。
这是可以放在项目根目录的 Dockerfile:
FROM eclipse-temurin:21-jre-ubi9-minimal ARG JAR_FILE COPY ${JAR_FILE} application.jar ENTRYPOINT ["java", "-jar", "/application.jar"]
我们指定了一个参数 JAR_FILE,它是要使用的 jar 文件的位置。
创建上述Dockerfile后,使用以下步骤创建Docker镜像:
为 Spring Boot 项目构建 jar 文件:
./gradlew bootJar # For Gradle build system
或者
./mvnw spring-boot:build-jar # For Maven build system
使用 Dockerfile 使用最新的 jar 文件构建 Docker 映像。在以下命令中,将 {IMAGE_NAME} 替换为所需的映像名称,将 {JAR_FILE} 替换为生成的 jar 文件的路径。图像名称还包含一个标签,例如 - mycompany/product-service:0.0.1-SNAPSHOT:
docker build --build-arg JAR_FILE={JAR_FILE} --tag {IMAGE_NAME} .
验证 Docker 镜像是否是使用以下命令构建的。您应该能够看到上面命令中指定名称的图像:
docker images
虽然可以轻松地将 Spring Boot uber jar 打包为 Docker 映像(如前面的方法中所述),但在 Docker 映像中按原样复制和运行 fat jar 有很多缺点。例如,
由于我们编译代码的频率比升级 Spring Boot 版本的频率高,因此最好将各个部分分开一些。如果我们将那些很少更改的jar文件放在应用层之前的层中,那么Docker通常只需要更改底层,并且可以从其缓存中选取其余的。
要创建分层的 Docker 镜像,我们需要首先创建分层的 jar。如今,它在 Gradle 和 Maven 中默认启用。您可以使用以下设置启用或禁用分层 jar 行为:
// build.gradle tasks.named("bootJar") { layered { enabled = false } }
// build.gradle.kts tasks.named("bootJar") { layered { enabled.set(false) } }
org.springframework.boot spring-boot-maven-plugin true
您甚至可以调整图层的创建方式。请参阅 gradle 或 maven 配置的文档。
下面是 Dockerfile,可用于利用分层 jar 并创建 Spring Boot 应用程序的分层 Docker 映像。
# Perform the extraction in a separate builder container FROM eclipse-temurin:21-jre-ubi9-minimal AS builder WORKDIR /builder # This points to the built jar file in the target folder # Adjust this to 'build/libs/*.jar' if you're using Gradle ARG JAR_FILE=target/*.jar # Copy the jar file to the working directory and rename it to application.jar COPY ${JAR_FILE} application.jar # Extract the jar file using an efficient layout RUN java -Djarmode=tools -jar application.jar extract --layers --destination extracted # This is the runtime container FROM eclipse-temurin:21-jre-ubi9-minimal WORKDIR /application # Copy the extracted jar contents from the builder container into the working directory in the runtime container # Every copy step creates a new docker layer # This allows docker to only pull the changes it really needs COPY --from=builder /builder/extracted/dependencies/ ./ COPY --from=builder /builder/extracted/spring-boot-loader/ ./ COPY --from=builder /builder/extracted/snapshot-dependencies/ ./ COPY --from=builder /builder/extracted/application/ ./ # Start the application jar - this is not the uber jar used by the builder # This jar only contains application code and references to the extracted jar files # This layout is efficient to start up and CDS friendly ENTRYPOINT ["java", "-jar", "application.jar"]
构建分层 Docker 镜像的步骤与构建基本 Docker 镜像相同。请参考那里。
如果我告诉你无需创建 Dockerfile 就可以创建 Docker 映像怎么办?我们可以使用 Cloud Native Buildpacks 直接从 Gralde 或 Maven 插件构建 docker 镜像。一些平台(如 Heroku 或 Cloud Foundry)使用 Buildpack 将提供的 jar 文件转换为可运行的映像。
Spring Boot 包括直接对 Maven 和 Gradle 的构建包支持。我们不需要包含任何额外的插件。只需运行以下命令:
./gradlew bootBuildImage # For gradle build system
或者
./mvnw spring-boot:build-image # For maven build system
上述命令生成默认名称为 {PROJECT_NAME}:${PROJECT_VERSION} 的图像。如果要配置生成图片的名称,可以按照以下步骤操作:
我们可以配置 bootBuildImage 任务来设置镜像的名称,如下所示:
// For build.gradle.kts val imagePrefix = "javarush" val dockerImageName = "docker-example" tasks.named("bootBuildImage") { imageName.set("${imagePrefix}/${dockerImageName}:${version}") }
// For build.gradle def imagePrefix = "javarush" def dockerImageName = "docker-example" tasks.named("bootBuildImage") { imageName = "${imagePrefix}/${dockerImageName}:${version}" }
我们可以配置 spring-boot-maven-plugin 使用另一个镜像名称,如下所示:
... javarush org.springframework.boot spring-boot-maven-plugin ${imagePrefix}/${project.artifactId}:${project.version}
我们甚至可以在运行构建镜像的命令时定义镜像的名称。
./gradlew bootBuildImage --imageName=javarush/docker-example:1.0.0 # For grade build system ./mvnw spring-boot:build-image -Dspring-boot.build-image.imageName=javarush/docker-example:1.0.0 # For maven build system
可以查看文档进一步配置Gradle或Maven插件。
这是我为任何 Spring Boot 应用程序创建 Docker 映像的首选方法。
创建 docker 镜像后,您需要确保它按预期工作。确保镜像创建完成后,可以直接使用 docker run 命令运行它。例如,
docker run -p "8080:8080" {IMAGE_NAME}
但是,这不是图像在生产应用程序中的使用方式。 Docker Compose 用于运行和管理多个 docker 镜像。
在这篇博客中,我们了解了如何使用不同的方法为 Spring Boot 应用程序构建 Docker 镜像。能够为您的应用程序构建 Docker 镜像是一项必须了解的技能,因为镜像是交付的内容。感谢您阅读本文直到最后。我很感激。我会在下一篇与你见面。一如既往,欢迎所有反馈和建议。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3