我想找出一个简单的Spring Boot应用程序可以减少Docker映像大小的多少。
Alpine Attempt
Therefore let's use a base image with Alpine Linux.
Dockerfile:
# use Alpine Linux for build stage
FROM alpine:3.10.1 as build
# install build dependencies
RUN apk --no-cache add openjdk11
RUN apk --no-cache add maven
...
这将从Dockerhub获取轻量级的Alpine Linux映像(〜6MB),并安装OpenJDK 11和Maven作为构建依赖项。 之后,我们可以构建Spring Boot应用程序:
...
# fetch maven dependencies
WORKDIR /build
COPY pom.xml pom.xml
RUN mvn dependency:go-offline
# build
COPY src src
RUN mvn clean package
...
如您所见,我们分两个步骤进行操作。 首先,我们下载所有依赖项,然后编译代码。 如果我们再次构建映像而不更改pom.xml文件,则结果将从缓存中获取。 这将节省一些时间,因为代码比依赖项进行更改的频率要高得多。
最后,我们创建第二个Docker映像,该映像仅包含执行所需的部分。 Docker将此功能称为“多阶段”功能,其中第一步是初步构建步骤,最后一步是执行映像:
...
# prepare a fresh Alpine Linux with JDK
FROM alpine:3.10.1
RUN apk --no-cache add openjdk11
# get result from build stage
COPY --from=build /build/target/*.jar /app.jar
VOLUME /tmp
EXPOSE 8080
CMD /usr/lib/jvm/default-jvm/bin/java -jar /app.jar
我们使用--from = build从第一阶段复制构建结果的参数。 所有其他部分将被删除:Maven,Java字节码,依赖项,...
结果有多大?
$ docker build -t lazy . && docker image ls | grep lazy
...
lazy latest 5f63318a3a0b 11 seconds ago 288MB
Jlink Attempt
我认为288MB太多了。 我记得Java 9将标准库拆分为模块。 有一个jlink工具可以仅使用必要的模块来构建JDK。 我们将jlink执行添加到MVN来电:
...
# build JDK with less modules
RUN /usr/lib/jvm/default-jvm/bin/jlink \
--compress=2 \
--module-path /usr/lib/jvm/default-jvm/jmods \
--add-modules java.base,java.logging,java.xml,jdk.unsupported, \
java.sql,java.naming,java.desktop,java.management, \
java.security.jgss,java.instrument \
--output /jdk-minimal
# fetch maven dependencies
...
另外,我们必须将最小的JDK复制到执行阶段:
# prepare a fresh Alpine Linux with JDK
FROM alpine:3.10.1
# get result from build stage
COPY --from=build /jdk-minimal /opt/jdk/
COPY --from=build /build/target/*.jar /app.jar
VOLUME /tmp
EXPOSE 8080
CMD /opt/jdk/bin/java -jar /app.jar
这样会减小尺寸吗?
$ docker build -t lazy . && docker image ls | grep lazy
...
lazy latest fbdc64bb6826 20 seconds ago 79.5MB
Summary
We removed ~200MB of unnecessary JDK modules. I like that. Maybe the size is even smaller if we use the Native Image feature of GraalVM?
结果:79.5MB
- 16MB JAR文件55MB OpenJDK 11“已链接”8.5MB高山Linux + Docker映像
Source Code: https://gist.github.com/gofabian/8a0f951bc1edc88b918ce1145ccfbb03