How to set up Spring Boot using Docker layered packaging

How to set up Spring Boot using Docker layered packaging

The Spring Boot project uses docker containers, jar and war layered packaging.

Spring Boot now supports layered packaging technology. Let's use it to speed up Docker packaging and build very quickly.

Layer settings

First, similar settings should be made in pom:

<plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>${spring-boot.version}</version>
                    <configuration>
                        <!-- Enable layered packaging support -->
                        <layers>
                            <enabled>true</enabled>
                        </layers>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

Declare the spring-boot-maven-plugin plugin, set the layers configuration, and enable layered support.

After packaging, we check the jar package or war package and find an additional layers.idx file, which contains a list of layered files.

- "dependencies":
  - "WEB-INF/lib-provided/"
  - "WEB-INF/lib/HikariCP-4.0.3.jar"
  - "WEB-INF/lib/aspectjweaver-1.9.5.jar"
  ...
  ...
- "spring-boot-loader":
  - "org/"
- "snapshot-dependencies":
  - "WEB-INF/lib/ms-fundmain-base-1.0-SNAPSHOT.jar"
  - "WEB-INF/lib/xpower-main-1.0.3-SNAPSHOT.jar"
  - "WEB-INF/lib/xpower-utils-1.0.3-SNAPSHOT.jar"
- "application":
  - "META-INF/"
  - "WEB-INF/classes/"
  - "WEB-INF/jetty-web.xml"
  - "WEB-INF/layers.idx"
  - "pages/"
  - "static/"

This file is the basis for the following layered settings.

If it is a jar, there is also a classpath.idx file, which lists all dependent jar packages.

When packaging, we can use docker build or docker-maven-plugin to achieve it.

Note: spring-boot-maven-plugin

It has Docker packaging function, but the download and packaging speed is too slow, which is very touching, so I don't recommend it here. --- The advantage is that you don't need to write Dockerfile, which is simple and convenient. The disadvantage is that you can't customize the Docker file.
The configuration is similar to the following:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <image>
            <!--Configure image name-->
            <name>127.0.0.1:5000/springcnscud/${project.name}:${project.version}</name>
            <!--After the image is packaged, it will be automatically pushed to the image warehouse-->
            <publish>true</publish>
        </image>
        <docker>
            <!--Docker remote management address-->
            <host>http://127.0.0.1:2375</host>
            <!-- Access without TLS -->
            <tlsVerify>false</tlsVerify>
            <!-- Docker push image repository configuration-->
            <publishRegistry>
                <!--Push mirror repository username-->
                <username>cnscud</username>
                <!--Push image repository password-->
                <password>123456</password>
                <!--Push mirror repository address-->
                <url>http://127.0.0.1:5000</url>
            </publishRegistry>
        </docker>
    </configuration>
</plugin>

If you use docker-maven-plugin + custom Dockerfile:

pom configuration:

    <plugin>
                    <groupId>io.fabric8</groupId>
                    <artifactId>docker-maven-plugin</artifactId>
                    <version>${docker.plugin.version}</version>
                    <configuration>
                        <!-- Docker Remote API -->
                        <!-- This machine can be commented out if it is not listening on port 2375 -->
                        <dockerHost>${docker.host}</dockerHost>
                        <!-- Docker image private server-->
                        <registry>${docker.registry}</registry>

                        <images>
                            <image>
                                <name>${docker.registry}/${docker.namespace}/${project.name}:${project.version}</name>
                                <build>
                                    <dockerFileDir>${project.basedir}</dockerFileDir>
                                </build>
                            </image>
                        </images>
                    </configuration>
                </plugin>

Let's take a look at the Dockerfile format in Spring Boot's jar mode:

# Layered construction, accelerated incremental construction FROM adoptopenjdk/openjdk8:centos-slim as builder

WORKDIR application
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
RUN java -Djarmode=layertools -jar app.jar extract && rm app.jar

FROM adoptopenjdk/openjdk8:centos-slim

LABEL maintainer="[email protected]"

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENV JAVA_OPTS="-Xms128m -Xmx256m"

WORKDIR application

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

EXPOSE 9001

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

Please modify the jdk according to your own situation, and use JarLauncher for jar.

If it is war, how to set it?

First of all, if you want to run it independently, you can use embedded tomcat or jetty, and do not set provider in pom

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>

This way, embedded tomcat will be included when packaging.

The Dockerfile is set up as follows:

# Layered construction, accelerated incremental construction FROM adoptopenjdk/openjdk8:centos-slim as builder

WORKDIR application
ARG JAR_FILE=target/*.war
COPY ${JAR_FILE} app.war
RUN java -Djarmode=layertools -jar app.war extract && rm app.war

FROM adoptopenjdk/openjdk8:centos-slim
LABEL maintainer="[email protected]"

ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENV JAVA_OPTS="-Xms128m -Xmx256m"

WORKDIR application

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

EXPOSE 8000

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

Note the file name, and run it using WarLauncher.

Using external tomcat

Without experimentation, building layers may be troublesome... But in theory, it is also possible, that is, use the unzipped war package instead of letting Tomcat unzip it itself

I won't try it here. The main point is to change the base package to tomcat, change the running ENTRYPOINT to tomcat, and copy the file to the container in the middle.

FROM tomcat:9.0

#Copy the xx.war file under target to /usr/local/tomcat/webapps/ ADD ./target/xx.war /usr/local/tomcat/webapps/

#EXPOSE port 8080

#Set the startup command ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]

This is the end of this article about Spring Boot using Docker layered packaging. For more related Docker layered packaging content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Implementation of Springboot packaging as Docker image and deployment
  • The simplest implementation of spring boot packaging docker image
  • Analysis of Springboot microservice packaging Docker image process
  • Spring Boot layered packaging Docker image practice and analysis (recommended)

<<:  Solve the problem of mysql's int primary key self-increment

>>:  Beginner's guide to building a website ⑥: Detailed usage of FlashFXP

Recommend

How to verify whether MySQL is installed successfully

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

Analyze the selection problem of storing time and date types in MySQL

In general applications, we use timestamp, dateti...

Pure CSS to achieve cool charging animation

Let’s take a look at what kind of charging animat...

MySql 5.6.36 64-bit green version installation graphic tutorial

There are many articles about MySQL installation ...

The solution record of Vue failing to obtain the element for the first time

Preface The solution to the problem of not being ...

HTML is something that web page creators must learn and master.

What are the benefits of learning HTML? 1: Easily...

How to set an alias for a custom path in Vue

How to configure custom path aliases in Vue In ou...

Vue uses vue meta info to set the title and meta information of each page

title: vue uses vue-meta-info to set the title an...

Solution to using html2canvas to process Dom elements with Baidu map into images

Problem 1: Baidu Map uses tiled images (the map i...

MySQL scheduled task implementation and usage examples

This article uses examples to illustrate the impl...

Experience of redesigning the homepage of TOM.COM

<br />Without any warning, I saw news on cnB...

Detailed discussion of the differences between loops in JavaScript

Table of contents Preface Enumerable properties I...