likes
comments
collection
share

SpringBoot Docker镜像构建方法以及Spring Boot Native构建方法

作者站长头像
站长
· 阅读数 27

spring-boot 容器化构建

代码链接:spring-boot-docker: springboot构建docker镜像方法 (gitee.com)

环境参数

  • 操作系统:WSL 2: Ubuntu 22.04.4 LTS jammy
  • graal版本: Oracle GraalVM 21.0.3+7.1 (build 21.0.3+7-LTS-jvmci-23.1-b37)
  • docker版本:Docker version 26.1.1, build 4cf5afa

docker镜像构建的三种方式

  • spring-boot-maven-plugin
  • jib-maven-plugin
  • docker-maven-plugin

spring-boot-maven-plugin

重要配置

pom插件配置如下:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>3.2.6</version>
            <configuration>
                <image>
                    <name>${project.artifactId}:latest</name>
                    <createdDate>${maven.build.timestamp}</createdDate>
                    <!-- <builder>
                        dashaun/builder-arm:20240403
                    </builder> -->
                </image>
            </configuration>
        </plugin>
    </plugins>
</build>

优缺点

优点:几乎不用配置,全部由插件完成,只需要指定构建参数即可。然后执行命令 ./mvnw clean spring-boot:build-image,直到构建完成。详细可以参考官方文档Packaging OCI Images :: Spring Boot。可以查看该镜像的结构,学习该结构,用于优化自己的构建。

缺点:依赖网络环境,需要连接github。因为配置文件可以指定builder,理论上可以基于默认的builder(paketobuildpakcs)来制作buidler解决网络依赖问题。但是专门为该插件定制镜像,复杂程度比直接用Dockerfile高多了,插件自身的可配置性也不够,还不如直接通过Dockerfile来构建。

jib-maven-plugin

重要配置

<build>
    <plugins>
        <plugin>
            <groupId>com.google.cloud.tools</groupId>
            <artifactId>jib-maven-plugin</artifactId>
            <version>3.4.2</version>
            <configuration>
                <from>
                    <image>eclipse-temurin:21-jre-alpine</image>
                </from>
                <to>
                    <image>${project.artifactId}:latest</image>
                </to>
                <container>
                    <mainClass>com.alex.springbootbuilddocker.SpringBootBuildDockerApplication</mainClass>
                    <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
                </container>
            </configuration>
            <!--绑定dockerBuild生命周期到package阶段,即执行./mvnw package后,会自动构建镜像-->
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>dockerBuild</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

这里只配置了基础镜像、构建名称和构建时间。其余配置可以参考jib/jib-maven-plugin at master · GoogleContainerTools/jib (github.com)。该插件还可以配置registry mirrors,配置文件的位置在${HOME}/.config/google-cloud-tools-java/jib下,不操作系统参考配置文档。

执行./mvnw clean package即可完成构建,然后通过docker-compose启动容器。

优缺点

优点:该插件为java项目通用插件、配置简单、可配置性较强,不依赖本地docker环境(goal改为build),且构建方式也为分层构建,可以构建tar包,还可以构建后推送到远程镜像仓库(goal改为build),且不需要spring-boot-maven-plugin插件 缺点:完全用插件配置,有一定学习成本。虽然插件本身的可配置性很强,但是还是不如Dockerfile灵活

docker-maven-plugin

重要配置

pom插件配置如下:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>3.2.6</version>
            <configuration>
                <mainClass>
                com.alex.springbootbuilddocker.SpringBootBuildDockerApplication
                </mainClass>
              	<!-- <platforms>
                         <platform>
                             <architecture>arm64</architecture>
                                <os>linux</os>
                         </platform>
                     </platforms> -->
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>exec</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <executable>bash</executable>
                <arguments>
                    <argument>-c</argument>
                    <argument>
                        <![CDATA[
                        mkdir target/extracted && \
                        java -Djarmode=layertools -jar target/*.jar extract --destination target/extracted
                        ]]>
                    </argument>
                </arguments>
            </configuration>
        </plugin>

        <plugin>
            <groupId>io.fabric8</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>0.44.0</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>build</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <images>
                    <image>
                        <name>${project.artifactId}:latest</name>
                        <build>
                            <dockerFile>${project.basedir}/Dockerfile</dockerFile>
                            <contextDir>${project.basedir}</contextDir>
                        </build>
                    </image>
                </images>
            </configuration>
        </plugin>
    </plugins>
</build>

Dockerfile配置如下:

FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
ARG EXTRACTED=target/extracted
COPY ${EXTRACTED}/dependencies/ ./
COPY ${EXTRACTED}/snapshot-dependencies/ ./
COPY ${EXTRACTED}/spring-boot-loader/ ./
COPY ${EXTRACTED}/application/ ./
ENV TZ="Asia/Shanghai"
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENTRYPOINT ["sh","-c","java org.springframework.boot.loader.launch.JarLauncher"]

该配置主要分为以下三点:

  1. spring-boot-maven-plugin,用于构建jar包,2.3后分层特性是默认开启的。参考官方文档:spring-boot-dockerMaven Plugin :: Spring Boot
  2. exec-maven-plugin,用来执行命令或脚本,用于将打好的jar包,拆成四个分层的文件夹
  3. docker-maven-plugin,用来构建镜像,该插件可以统一镜像名、镜像版本与pom文件一致

上面的配置同下面的脚本功能一致,脚本的优点是简单易懂,缺点是硬编码较多

./mvnw clean package -DskipTests

mkdir target/extracted
java -Djarmode=layertools -jar target/*.jar extract --destination target/extracted

docker build . -t spring-boot-build-docker:latest

优缺点

该方式的优点是各步骤相互独立,且每一步都是简单容易理解的、扩展灵活,同时不依赖网络环境。

缺点是每一步都需要理解并自己配置。

该方式多用于实际生产中。

spring boot native 镜像构建

环境参数

  • 操作系统:WSL 2: Ubuntu 22.04.4 LTS jammy
  • graal版本: Oracle GraalVM 21.0.3+7.1 (build 21.0.3+7-LTS-jvmci-23.1-b37)
  • docker版本:Docker version 26.1.1, build 4cf5afa

重要配置

<build>
    <plugins>
        <plugin>
            <groupId>org.graalvm.buildtools</groupId>
            <artifactId>native-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <image>
                    <name>${project.artifactId}-native:latest</name>
                    <createdDate>${maven.build.timestamp}</createdDate>
                    <!-- <builder>
                    		     dashaun/builder-arm:20240403
                    		 </builder> -->
                </image>
            </configuration>
        </plugin>
    </plugins>
</build>

构建本地可执行文件

./mvnw clean native:compile -Pnative

该命令依赖gcc和zlib,需要先执行(不同环境需要的依赖不一样,可以先执行上面的编译命令,再根据报错添加所需依赖库)

sudo apt-get install gcc
sudo apt-get install zlib1g-dev

构建成功后,启动应用,执行

./target/spring-boot-build-docker

启动速度极快,几十毫秒

该方式无需联网,可以构建后通过Dockerfile继续构建docker镜像,但是需要保持构建环境和运行环境的类库兼容性。可以考虑通过同一个基础镜像构建构建镜像和运行镜像。

构建OCI镜像

./mvnw clean spring-boot:build-image -Pnative

通过docker-compose.yaml启动容器,同样也是极快启动

该方式是通过paketobuildpacks在docker容器中编译和构建镜像,能保证编译环境与运行环境的一致性,屏蔽了不同操作系统版本的影响。该方式是比较适合方式。但是构建过程中有些依赖需要从github上下载,有网络联通问题,且插件参数不能配置镜像或离线构建。

转载自:https://juejin.cn/post/7376926496366723098
评论
请登录