Spring Boot layered packaging Docker image practice and analysis (recommended)

Spring Boot layered packaging Docker image practice and analysis (recommended)

1. Prepare the Spring Boot project

Simple, skip
Spring boot version > 2.3.x can simply write a hello world

2. Perform relevant configuration

Many blogs on the Internet emphasize that you need to manually configure the pom.xml to enable layered packaging:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <!--Enable tiered compilation support-->
                <layers>
                    <enabled>true</enabled>
                </layers>
            </configuration>
        </plugin>
    </plugins>
</build>

In version 2.3.x, it is a new feature and needs to be manually configured and enabled. However, the current Spring Boot version (using version 2.6.1) does not require manual configuration and supports this feature by default. (According to some blogs, it is enabled by default after version 2.4.x)

The current official documentation (version 2.6.0) also states that it is supported by default, but manual configuration is required only when this feature is not needed:

The repackaged archive includes the layers.idx file by default. To disable this feature, you can do so in the following manner:

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

3. package

Execute mvn package to package and obtain the jar package file.

In fact, the essence is to use the repackage of the spring-boot-maven plug-in to get the complete jar package containing dependencies and the original jar package (the suffix .original is automatically added)
Open the jar package and you will find classpath.idx and layers.idx files in the BOOT-INF folder. Open them and take a look:

classpath.idx

- "BOOT-INF/lib/logback-classic-1.2.7.jar"

- "BOOT-INF/lib/logback-core-1.2.7.jar"

- "BOOT-INF/lib/log4j-to-slf4j-2.14.1.jar"

- "BOOT-INF/lib/log4j-api-2.14.1.jar"

- "BOOT-INF/lib/jul-to-slf4j-1.7.32.jar"

- "BOOT-INF/lib/jakarta.annotation-api-1.3.5.jar"

- "BOOT-INF/lib/snakeyaml-1.29.jar"

- "BOOT-INF/lib/jackson-databind-2.13.0.jar"

- "BOOT-INF/lib/jackson-annotations-2.13.0.jar"

- "BOOT-INF/lib/jackson-core-2.13.0.jar"

- "BOOT-INF/lib/jackson-datatype-jdk8-2.13.0.jar"

- "BOOT-INF/lib/jackson-datatype-jsr310-2.13.0.jar"

- "BOOT-INF/lib/jackson-module-parameter-names-2.13.0.jar"

- "BOOT-INF/lib/tomcat-embed-core-9.0.55.jar"

- "BOOT-INF/lib/tomcat-embed-el-9.0.55.jar"

- "BOOT-INF/lib/tomcat-embed-websocket-9.0.55.jar"

- "BOOT-INF/lib/spring-web-5.3.13.jar"

- "BOOT-INF/lib/spring-beans-5.3.13.jar"

- "BOOT-INF/lib/spring-webmvc-5.3.13.jar"

- "BOOT-INF/lib/spring-aop-5.3.13.jar"

- "BOOT-INF/lib/spring-context-5.3.13.jar"

- "BOOT-INF/lib/spring-expression-5.3.13.jar"

- "BOOT-INF/lib/spring-boot-2.6.1.jar"

- "BOOT-INF/lib/spring-boot-autoconfigure-2.6.1.jar"

- "BOOT-INF/lib/slf4j-api-1.7.32.jar"

- "BOOT-INF/lib/spring-core-5.3.13.jar"

- "BOOT-INF/lib/spring-jcl-5.3.13.jar"

- "BOOT-INF/lib/spring-boot-jarmode-layertools-2.6.1.jar"

layers.idx

- "dependencies":

- "BOOT-INF/lib/"

- "spring-boot-loader":

- "org/"

- "snapshot-dependencies":

- "application":

- "BOOT-INF/classes/"

- "BOOT-INF/classpath.idx"

- "BOOT-INF/layers.idx"

- "META-INF/"

Verify again:

Layered information ok

4. Dockerfile

The Dockerfile file is also relatively conventional. It just uses the jarmode command to decompress the jar package before packaging the image. Then, during the packaging process, different layers are copied in sequence, and the application layer with the greatest possibility of change is placed at the end. In this way, the previous layers that have no changes can directly use Docker's cache to improve packaging efficiency.

FROM eclipse-temurin:8-jre-focal as builder

WORKDIR application

ARG JAR_FILE=target/*.jar

COPY ${JAR_FILE} application.jar

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

FROM eclipse-temurin:8-jre-focal

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/ ./

ENV TZ="Asia/Shanghai"

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

ENV JVM_OPTS=""

ENV JAVA_OPTS=""

ENTRYPOINT ["sh","-c","java $JVM_OPTS $JAVA_OPTS org.springframework.boot.loader.JarLauncher"]

5. Application modification & dive analysis

In fact, if you only package the image once, the advantages of layering will not be reflected, so you need to modify some content and then package it again (or multiple times, but the essence is the same, so only modify it once here)
Modify some application codes:

Re-pack the jar package and re-image, so that two images are obtained:

Use dive to analyze the two images:

It can be found that until the application layer (application/application/) is changed, the Id and Digest of the layers on both sides are exactly the same, so these layers can be reused, and the same layer will only be stored individually in the docker directory, which can greatly reduce the time for container compilation and push.
(The understanding of the specific layering of docker images is still limited, and I will learn more about it later)

This is the end of this article about the practice and analysis of Spring Boot layered packaging Docker image. For more relevant Spring Boot layered packaging Docker image content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Thoroughly understand the implementation of Docker image layering
  • Docker image layering and dockerfile writing skills
  • Detailed explanation of the principle of Docker image layering
  • A brief analysis of the considerations for Docker image layering
  • In-depth understanding of the layering of docker images (a must-read for beginners)

<<:  In-depth understanding of the seven communication methods of Vue components

>>:  Sample code for implementing dynamic glowing special effects animation of circles using pure CSS3

Recommend

How to install MySQL 5.7 on Ubuntu and configure the data storage path

1. Install MySQL This article is installed via AP...

How to visualize sketched charts in Vue.js using RoughViz

introduce A chart is a graphical representation o...

MySQL table and column comments summary

Just like code, you can add comments to tables an...

Vue uses three methods to refresh the page

When we are writing projects, we often encounter ...

How to run the react project on WeChat official account

Table of contents 1. Use the a tag to preview or ...

Summary of various common join table query examples in MySQL

This article uses examples to describe various co...

Four methods of using JS to determine data types

Table of contents Preface 1. typeof 2. instanceof...

Super detailed MySQL usage specification sharing

Recently, there have been many database-related o...

How to use the Linux seq command

1. Command Introduction The seq (Sequence) comman...

Understanding the CSS transform-origin property

Preface I recently made a fireworks animation, wh...

Proxy_pass method in multiple if in nginx location

1. First, let's review the relevant knowledge...

Detailed explanation of Angular routing basics

Table of contents 1. Routing related objects 2. L...

How to verify whether MySQL is installed successfully

After MySQL is installed, you can verify whether ...

JavaScript imitates Jingdong magnifying glass special effects

This article shares the specific code of JavaScri...