您已经创建了一个 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.named7e534d3bd056dd41a31367722242bb81("bootJar") { layered { enabled.set(false) } }
7a7963d93b467c9ab002af7a44e64bd4 c70346ba2d7be186a93fef826469bd2f 5ac54a929980b32fdd2e48b6a8da067c c4222ff3007372f15ec728b963e717b6 33ca7039399a4759a8764ea38765dd46 05a8acc5c31084a4f61ade01873802caorg.springframework.boot192ca2f7b8c770b01c8f81e6bdd5b947 9bc4cbb67f66e148869423c0d27e5f90spring-boot-maven-pluginb68fb17cb904a46b73e6272850323873 f9d9f4a8f32d97f3ef0c10742ed31240 e72a6d14eb9b15c1c12186917135155b d79c9ed277a80783d30ca709c63bc2d1true1d1b3b9680fd03597e1ed3fa2b627c20 98a78221d1c969529e0b9f39a24b39b0 4b1b9d85fe86862ae3eab7e2045cf8a0 9424ec9162a9b85f34067d0c54f34b32 f3567a435ac6132b26525998d793443b f82c24fb6fac67972f6e79c18ccef56a 1755c7176d4002e2a322de4f48c796fa
您甚至可以调整图层的创建方式。请参阅 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.named2e00f062267875fb651ebdd74d6c6eb1("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 使用其他镜像名称,如下所示:
a01741acb88936e4cea4237317380dd9 d025b153d4d19d25710ee358f3c66eafjavarush515db9ab99a6918e33f7eeaddd64c8cf 86cd8b5c0fbd401fb69261955cf13796 ... c70346ba2d7be186a93fef826469bd2f 5ac54a929980b32fdd2e48b6a8da067c c4222ff3007372f15ec728b963e717b6 33ca7039399a4759a8764ea38765dd46 05a8acc5c31084a4f61ade01873802caorg.springframework.boot192ca2f7b8c770b01c8f81e6bdd5b947 9bc4cbb67f66e148869423c0d27e5f90spring-boot-maven-pluginb68fb17cb904a46b73e6272850323873 f9d9f4a8f32d97f3ef0c10742ed31240 dc0870658837139040642baa5555a380 8a11bc632ea32a57b3e3693c7987c420${imagePrefix}/${project.artifactId}:${project.version}df406f776eecbaf16b62325323196f14 f8e950ebc6c1ea27f76cf997b9216fe6 4b1b9d85fe86862ae3eab7e2045cf8a0 9424ec9162a9b85f34067d0c54f34b32 f3567a435ac6132b26525998d793443b f82c24fb6fac67972f6e79c18ccef56a 1755c7176d4002e2a322de4f48c796fa
我们甚至可以在运行构建镜像的命令时定义镜像的名称。
./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
You can see the documentation to further configure Gradle or Maven plugin.
This is my go-to method to create a Docker image for any Spring Boot application.
Once you create a docker image, you need to make sure that it works as expected. After you make sure that the image is created, you can directly run it using the docker run command. For example,
docker run -p "8080:8080" {IMAGE_NAME}
But, this is not how images are used in production applications. Docker Compose is used to run and manage multiple docker images.
In this blog, we have seen how to build Docker images for Spring Boot applications using different methods. Being able to build docker images for your apps is a must skill to know because the image is what gets delivered. Thanks for reading the article till the end. I appreciate it. I will meet you in the next one. As always, all feedback and suggestions are welcome.
以上是使用 Buildpack 创建 Spring Boot 应用程序的 Docker 映像的详细内容。更多信息请关注PHP中文网其他相关文章!