Spring Boot应用分层构建Docker Image

前一直使用 Dockerfile 的方式将 Spring Boot应用 构建成 Docker Image , 发现jar包只有十几兆,但是构建出现的镜像有几百兆,传输的时候非常慢。后来发现 spring-boot-maven-plugin 插件可以分层构建 Docker Image ,尝试了一下,效果挺不错。

常用构建方式

Spring Boot 应用打包成 Docker Image 最常用的方式使用编写 Dockerfile ,使用 docker build 命令手动打包。

Dockerfile 内容如下:

FROM openjdk:17
WORKDIR /app
COPY target/*.jar /app/app.jar
ENTRYPOINT ["java","-jar","/app/app.jar"]
  1. 构建过程:

image.png

  1. 构建结果:

image.png 使用 docker images 查看镜像,可以发现多了两个镜像: webflux_demo_fileopenjdkwebflux_demo_file 是应用程序最终构建的镜像, openjdk 是被依赖的基础镜像。从镜像大小我们可以看到 webflux_demo_file 镜像共796m,而基础镜像 openjdk 就占了471m。

分层构建

spring boot 2.3 之后的 spring-boot-maven-plugin 插件支持将应用程序构建成 Docker Image ,并且支持分层构建、将镜像推送到镜像仓库等功能。

要使用 spring-boot-maven-plugin 插件分层构建应用程序,需要在 pom 文件中加入一些配置。

  1. 修改 pom 文件

spring-boot-maven-plugin 增加配置开启分层构建并配置分层的方式。

<properties>
    <!--声明时间戳的格式化方式-->
    <maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
</properties>


<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <layers>
            <!--开启分层构建-->
            <enabled>true</enabled>
             <!--构建配置-->
            <configuration>${project.basedir}/layers.xml</configuration>
        </layers>
        <image>
            <!--镜像名称, 使用构建时间作为镜像的版本号-->
            <name>example.com/webflux_demo:${maven.build.timestamp}</name>
        </image>
    </configuration>
</plugin>
  1. 创建 layers.xml 文件

layers.xml 文件配置了分层构建的方式,内容如下:

<layers xmlns="http://www.springframework.org/schema/boot/layers"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/boot/layers
                          https://www.springframework.org/schema/boot/layers/layers-2.6.xsd">
    <application>
        <into layer="spring-boot-loader">
            <include>org/springframework/boot/loader/**</include>
        </into>
        <into layer="application" />
    </application>
    <dependencies>
        <into layer="application">
            <includeModuleDependencies />
        </into>
        <into layer="snapshot-dependencies">
            <include>*:*:*SNAPSHOT</include>
        </into>
        <into layer="dependencies" />
    </dependencies>
    <layerOrder>
        <layer>dependencies</layer>
        <layer>spring-boot-loader</layer>
        <layer>snapshot-dependencies</layer>
        <layer>application</layer>
    </layerOrder>
</layers>
  1. 构建镜像

使用 mvn spring-boot:build-image 命令或者在 maven工具 中双击 spring-boot:build-image 开始构建镜像。如图 image.png

  1. 构建信息

构建信息过多,这里截取部分。如下图 image.png

  1. 构建结果

使用 docker images 查看镜像,可以看到使用这种方式构建的镜像只有282m。比使用之前的镜像小了一半。

image.png

美中不足的是构建的时候需要从github下载一个包,导致构建时间很长


作者:不可食用盐
链接:Spring Boot应用分层构建Docker Image - 掘金