跳到主要内容

Best Practice for Spring Boot Working with Docker

· 阅读需 2 分钟
Xiao Yu

This article I will talking about How to package spring boot app into a docker image , and how to optimize the size of the image.

a basic example

First of all, let's take a look at the simplest dockerfile

# 最好是选择jre和slim后缀的基础镜像,它同时对linux和JDK做裁剪,能最小化镜像的体积而不影响java程序的运行性能
# for java8 we can try openjdk:8-jre-alpine
FROM openjdk:11-jre-slim

WORKDIR /app

ARG JAR_FILE=./target/*.jar
COPY ${JAR_FILE} app.jar

ENTRYPOINT [ "java", "-jar", "/app/app.jar" ]

But there are several weaknesses:

  • the container will be started by this user by default: root, there are potential safety risk
  • the jar file is too fat, which means the image layer is not been handling well, each time we change the code, the image build time may be too long
  • the basic image is too huge (try to use the jre instead of the jdk)

get a better image layer

https://github.com/wagoodman/dive


FROM eclipse-temurin:17-jre-jammy as builder
ARG JAR_FILE=target/*.jar
WORKDIR application
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract

################

FROM eclipse-temurin:17-jre-jammy
MAINTAINER xiaoyureed <rainx000@qq.com>
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 JVM_OPTS="-Xmx256m -Xms256m" \
HALO_WORK_DIR="/root/.halo2" \
SPRING_CONFIG_LOCATION="optional:classpath:/;optional:file:/root/.halo2/" \
TZ=Asia/Shanghai

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

EXPOSE 8080
ENTRYPOINT ["sh", "-c", "java ${JVM_OPTS} -Djava.security.egd=file:/dev/./urandom org.springframework.boot.loader.JarLauncher ${0} ${@}"]

modularize the project

https://sergiomartinrubio.com/articles/build-a-docker-jre-image-with-java-17-and-spring/

Making your project modularized is a great way to reduce the final docker images size

Another way to conduct this action (modularization) is by using JLink

multi-stage build

try to make the native image

The image size can reduce greatly by using native image, and the other aspects such as the time taken to start, the memory occupied.... Generally speaking, there are so many benefits.

reference materials

https://github.com/halo-dev/halo can be taken as a best practice

https://snyk.io/blog/best-practices-to-build-java-containers-with-docker/ https://blog.monosoul.dev/2022/04/25/reduce-java-docker-image-size/

https://mritd.com/2022/11/08/java-containerization-guide/ tips for java docker image

https://hub.docker.com/_/eclipse-temurin/tags?page=1&name=17 the jdk17 base image.

https://zhuanlan.zhihu.com/p/245645260 tips, which base image we should choose

https://github.com/GoogleContainerTools/jib maven plugin produced by google to generate docker image.

Loading Comments...