首页  >  文章  >  Java  >  使用 Buildpack 创建 Spring Boot 应用程序的 Docker 映像

使用 Buildpack 创建 Spring Boot 应用程序的 Docker 映像

WBOY
WBOY原创
2024-09-08 20:31:02872浏览

Creating Docker Image of Spring Boot Application using Buildpacks

介绍

您已经创建了一个 Spring Boot 应用程序。它在您的本地计算机上运行良好,现在您需要将该应用程序部署到其他地方。在某些平台上,您可以直接提交jar文件,它将被部署。在某些地方,您可以启动虚拟机,下载源代码,构建并运行它。但是,大多数时候您需要使用容器来部署应用程序。大多数时候,Docker 用于在容器中构建和运行镜像。此外,当您将 jar 文件上传到某些平台时,应用程序会在后台的容器内运行。

因此,在本博客中,我们将看到 3 种不同的方法来为给定的 Spring Boot 应用程序构建 Docker 映像。让我们开始吧:

基础容器镜像

为任何应用程序构建 Docker 映像的简单且不充分的方法是使用一个简单的 Dockerfile,该文件将 jar 文件复制到映像中并使用 java -jar 命令运行它。

创建 Dockerfile

这是 Dockerfile,您可以将其放在项目的根目录中:

FROM eclipse-temurin:21-jre-ubi9-minimal

ARG JAR_FILE

COPY ${JAR_FILE} application.jar

ENTRYPOINT ["java", "-jar", "/application.jar"]

我们指定了一个参数 JAR_FILE,它是要使用的 jar 文件的位置。

构建 Docker 镜像

创建上述 Dockerfile 后,使用以下步骤创建 Docker 镜像:

  1. 为 Spring Boot 项目构建 jar 文件:

    ./gradlew bootJar # For Gradle build system
    

    或者

    ./mvnw spring-boot:build-jar # For Maven build system
    
  2. 使用 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} .
    
  3. 验证 Docker 镜像是否是使用以下命令构建的。您应该能够看到上面命令中指定名称的图像:

    docker images
    

使用分层 Jar 的高效容器镜像

虽然可以轻松地将 Spring Boot uber jar 打包为 Docker 镜像(如前面的方法中所述),但在 Docker 镜像中按原样复制和运行 fat jar 有很多缺点。例如,

  • 在不解压的情况下运行 uber jar 会产生一些额外的开销。
  • 将应用程序的代码及其所有依赖项放在单个层中并不是最佳选择。

由于我们编译代码的频率比升级 Spring Boot 版本的频率高,因此最好将各个部分分开一些。如果我们将那些很少更改的jar文件放在应用层之前的层中,那么Doc​​ker通常只需要更改底层,并且可以从其缓存中选取其余的。

启用分层 Jar

要创建分层 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

下面是 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 镜像的步骤与构建基本 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} 的图像。如果你想配置生成图片的名称,可以按照以下步骤操作:

为 Gradle 构建系统配置镜像名称

我们可以配置 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}"
}

为 Maven 构建系统配置镜像名称

我们可以配置 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.

Running Docker Container

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.

Conclusion

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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn