Spring Boot Setup Method Using Docker Hierarchical Packaging
- 2021-11-02 03:43:53
- OfStack
The Spring Boot project uses a layered package of docker containers, jar, and war.
Spring Boot now supports layered packaging technology. Let's also use 1 to speed up Docker packaging, and the construction speed will be very fast.
Hierarchical setting
First of all, pom should be set similarly:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<!-- Enable hierarchical packaging support -->
<layers>
<enabled>true</enabled>
</layers>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Declared
spring-boot-maven-plugin
Plug-in, set layers configuration, and turn on hierarchical support.
After packing, we check the jar package or war package, and we will find that there is an extra layers. idx file, which contains a list of hierarchical 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 hierarchical settings.
If it's jar, there's another one in it
classpath.idx
File, which lists all dependent jar packages.
When packaging, we can use docker build or use
docker-maven-plugin
Plug-in to implement.
Note: spring-boot-maven-plugin plug-in
docker itself package function, but download package speed is too slow, very touching, all here is not recommended.---The advantage is not to write Dockerfile, simple and convenient, the disadvantage is that you can not customize Docker file.
The configuration is similar to the following:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<!-- Configure the image name -->
<name>127.0.0.1:5000/springcnscud/${project.name}:${project.version}</name>
<!-- After the image is packaged, it is automatically pushed to the image warehouse -->
<publish>true</publish>
</image>
<docker>
<!--Docker Remote management address -->
<host>http://127.0.0.1:2375</host>
<!-- Do not use TLS Visit -->
<tlsVerify>false</tlsVerify>
<!-- Docker Push Mirror Warehouse Configuration -->
<publishRegistry>
<!-- Push Mirror Warehouse User Name -->
<username>cnscud</username>
<!-- Push Mirror Warehouse Password -->
<password>123456</password>
<!-- Push Mirror Warehouse 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 there is no listening 2375 Port -->
<dockerHost>${docker.host}</dockerHost>
<!-- Docker Mirror image private service -->
<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 look at the Dockerfile format in jar mode of Spring Boot:
# Hierarchical construction , Accelerate incremental build
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="cnscud@gmail.com"
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 in the case of jar.
If it is war, how to set it up?
First of all, if you want to run 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>
In this way, the embedded tomcat will be included when packaging.
Dockerfile settings are as follows:
# Hierarchical construction , Accelerate incremental build
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="cnscud@gmail.com"
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 filename and run using WarLauncher.
Using external tomcat
Without experimentation, building layers can be cumbersome... but in theory, it is possible to use the decompressed war package instead of letting tomcat decompress itself
I won't try it here. The main point is that the basic package is replaced by tomcat, the running ENTRYPOINT is replaced by tomcat, and the files are copied to the container in the middle.
FROM tomcat:9.0
# Will target Under xx.war Copy to /usr/local/tomcat/webapps/ Under
ADD ./target/xx.war /usr/local/tomcat/webapps/
# Port
EXPOSE 8080
# Set the startup command
ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]