SpringBoot 2.3.0 + Docker realizes layered packaging

SpringBoot + Docker layered packaging

background

SpringBoot uses the org.springframework.boot:spring-boot-maven-pluginMaven plugin to compile the project into a jar package by default . The jar package compiled by default is a whole, which java -jarcan be started directly by command. After combining with docker, we can package it into a Docker image by DockerFileor Docker Compose. But every time Maven compiles the SpringBoot project file into a full jar package in the target folder, the jar package contains our own code and dependent third-party jar packages, often a jar package is above 100M, which leads to When combined with docker packaging, the docker pushfull jar package will be uploaded each time . Recently, SpringBoot 2.3.0 was released, and the update includes support for layered packaging. Let's take a look at how SpringBoot combined with Docker can achieve layered packaging.

Demo project warehouse: https://gitee.com/wxdfun/springboot-layers.git

analysis

How to compile the SpringBoot project into a jar package and how to use Docker will not be introduced. You can go to Baidu and enter today's topic directly. A docker image analysis tool will be used in this article dive. For installation and use, please refer to the document https://github.com/wagoodman/dive

Let's take a look at the original SpringBoot packaging and DockerFile compilation image. Let's create a simple demo project for testing.

Pom configuration SpringBoot packaging plugin

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

DockerFile file in the root directory

FROM openjdk:8-jre

MAINTAINER [email protected]

WORKDIR application

EXPOSE 36665

ADD ./target/*.jar ./app.jar

CMD java  -jar app.jar

Then we execute the relevant command package

mvn clean package
docker build . -t hc.registry.docker.com:5000/springboot-layers:1.0.0

docker compile image

Let's take a look at the layering of this docker image first, use docker inspectand divetake a look respectively .

docker inspect hc.registry.docker.com:5000/springboot-layers:1.0.0

[External link image transfer failed. The source site may have an anti-leech link mechanism. It is recommended to save the image and upload it directly (img-WUNntqU3-1592193616881)(https://imgb.hnhcyy.com/ctr_cloud/doc/md/20200615104414.jpg )]

dive hc.registry.docker.com:5000/springboot-layers:1.0.0

dive_1.0.0

Next, we change a little java code and repeat the above steps to see the problem.

[External link image transfer failed. The source site may have an anti-leech link mechanism. It is recommended to save the image and upload it directly (img-1iaRTW16-1592193616883)(https://imgb.hnhcyy.com/ctr_cloud/doc/md/20200615105447.jpg )]

mvn clean package
docker build . -t hc.registry.docker.com:5000/springboot-layers:1.0.1

docker inspect hc.registry.docker.com:5000/springboot-layers:1.0.1

inspect_1.0.1

Only the last part of the docker image layered file is different from the last compilation.

dive hc.registry.docker.com:5000/springboot-layers:1.0.1

[External link image transfer failed. The source site may have an anti-leech link mechanism. It is recommended to save the image and upload it directly (img-aCNRsyij-1592193616885)(https://imgb.hnhcyy.com/ctr_cloud/doc/md/20200615105947.jpg )]

It can be seen that we only changed a few characters, and docker still uploaded the full jar package of springboot to us when packaging it.

Retrofit

Recently, springboot 2.3.0 was released, supporting springboot hierarchical packaging. Let's see how the new features can be combined with docker. Upgrade springboot to depend on 2.3.0.RELEASE.

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.0.RELEASE</version>
        <relativePath/>
    </parent>

Add configuration to support layered packaging in the SpringBoot-maven plugin

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <layers>
                        <enabled>true</enabled>
                    </layers>
                </configuration>
            </plugin>
        </plugins>
    </build>

Perform the packaging analysis operation again mvn clean package, and now we can use the following command to see the jar package structure of our springboot2.3.0 hierarchical packaging and compilation
java -Djarmode=layertools -jar target/springboot-layers-1.0.0.jar list

layertools_list

You can see that layertools recognizes that the dependencies in the jar package are packaged into different folders, and then we modify the original dockerfile

FROM openjdk:8-jre as builder

WORKDIR application

ADD ./target/*.jar ./app.jar

RUN java -Djarmode=layertools -jar app.jar extract

FROM openjdk:8-jre

MAINTAINER [email protected]

WORKDIR application

COPY --from=builder application/dependencies/ ./

COPY --from=builder application/spring-boot-loader/ ./

COPY --from=builder application/snapshot-dependencies/ ./

COPY --from=builder application/application/ ./

EXPOSE 36665

ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

This dockerfile means that a temporary image build is marked as builder, and the full jar package is loaded once, and then the java -Djarmode=layertools -jar app.jar extractcommand is executed to decompose the jar package into hierarchical packaging directories, and a new image is built again, and the hierarchical directories are divided into batches according to the list of directories. Load into the docker image.

Build the docker image againdocker build . -t hc.registry.docker.com:5000/springboot-layers:2.0.0

docker inspect hc.registry.docker.com:5000/springboot-layers:2.0.0

inspect_2.0.0

You can see that in the file layering of the docker image, there are more levels. Let's change the java code and build it again.

Changes 2.0.1

mvn clean package
docker build . -t hc.registry.docker.com:5000/springboot-layers:2.0.1

Analyze the docker image level again

docker inspect hc.registry.docker.com:5000/springboot-layers:2.0.1

inspect_2.0.1

Still only the last file layer has changed, use dive to analyze it

dive hc.registry.docker.com:5000/springboot-layers:2.0.1

dive_2.0.1

A magical thing happened, this time the changes in docker only have 4.6k file changes. Push the 2.0.0 and 2.0.1 docker images separately to verify whether only these two changed layered files are re-uploaded

push_2.0.0

push_2.0.1

It can be found that, as we thought, the 2.0.1 docker image push change file is the only 4.6k file marked above, and the uploaded hierarchical file is also greatly reduced. Finally, we can start our mirror to verify the success.

docker run -p 36665:36665 hc.registry.docker.com:5000/springboot-layers:2.0.1

result

result

After configuring the springboot 2.3.0 version to support hierarchical packaging, and the dockerfile file is also changed to the corresponding format, we can indeed achieve the desired effect. What we re-upload each time is only the code we wrote, third-party dependencies, SpringBoot internal configuration, snapshot dependencies, these SpringBoot are packaged for us in different folders, and then rely on the docker's hierarchical characteristics to add files in stages. The effect of layered packaging can be achieved. Friends who want to find out can do it java -Djarmode=layertools -jar target/springboot-layers-2.0.1.jar extract, and then look at the contents of the file in the figure below to make the truth clear.

SpringBoot internal configuration, snapshot dependency, these SpringBoot are packaged in different folders for us, and then relying on the layered characteristics of docker, adding files in stages can achieve the effect of layered packaging. Friends who want to find out can do it java -Djarmode=layertools -jar target/springboot-layers-2.0.1.jar extract, and then look at the contents of the file in the figure below to make the truth clear.

image-20200615115315550

Guess you like

Origin blog.csdn.net/ttzommed/article/details/106759670