springboot可以把项目打包成app了,docker打包版

上一篇文章介绍了如果通过graalVM 打包java本地应用,这里我们继续介绍如何通过docker打包java的原生镜像。

在操作之前,我们先思考一下问题:为什么要打包成docker容器呢?

就是为了云原生!

或者说,java的本地app打包功能的支持,一大原因就是为了适应云原生时代,所以支持容器也是必然的选择了。

java原生app docker化后部署架构图

下面开始展现代码实现。

代码和依赖

代码部分和本地环境配置方面,和上篇文章 springboot可以把项目打包成app了,Graal打包版 里的graalvm-native-app项目完全一致,就不多说了。

接下来是打包部分的差异。

要将项目打包成docker的原生应用镜像,需要先在操作系统上安装docker环境。

  • linux: 参考官方文档选择自己的发行版安装
  • mac/windows: 个人开发这可以安装docker desktop应用,一键安装,很简单。

docker 安装好 和 nik包(见上文)安装完成后,我们的环境就准备好了。

打包

要想打包成docker 原生app镜像,需要依赖一个paketobuildpacks/builder-jammy-java-tiny镜像。

项目打包过程中也会自动下载,但是提前准备好会提升打包效率。

1
docker pull paketobuildpacks/builder-jammy-java-tiny:latest

镜像pull成功后,就可以执行打包命令了,理论上,不用任何操作,一条命令即可将springboot项目打包成docker镜像

1
mvn -Pnative spring-boot:build-image

此命令和下面的配置效果一样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-image</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

都是触发springboot构建插件里的构建docker镜像逻辑。

下面是部分构建过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
[INFO] --- spring-boot-maven-plugin:3.4.3:build-image (default-cli) @ graalvm-native-app ---
[INFO] Building image 'docker.io/library/graalvm-native-app:0.0.1-SNAPSHOT'
[INFO]
[INFO] > Pulling builder image 'docker.io/paketobuildpacks/builder-jammy-java-tiny:latest' 100%
[INFO] > Pulled builder image 'paketobuildpacks/builder-jammy-java-tiny@sha256:c5c53c656d9151071482c79f2460aee477e25d05d83b5286549074707d1f76f1'
[INFO] > Pulling run image 'docker.io/paketobuildpacks/run-jammy-tiny:latest' for platform 'linux/arm64' 12%
[INFO] > Pulling run image 'docker.io/paketobuildpacks/run-jammy-tiny:latest' for platform 'linux/arm64' 32%
[INFO] > Pulling run image 'docker.io/paketobuildpacks/run-jammy-tiny:latest' for platform 'linux/arm64' 100%
[INFO] > Pulled run image 'paketobuildpacks/run-jammy-tiny@sha256:0c5ac79d549c4b077a7d857631f817f8b573f5da2c109a51f320ee584d44d3f2'
[INFO] > Executing lifecycle version v0.20.6
[INFO] > Using build cache volume 'pack-cache-064fa27f6606.build'
[INFO]
[INFO] > Running creator
[INFO] [creator] ===> ANALYZING
[INFO] [creator] Image with name "docker.io/library/graalvm-native-app:0.0.1-SNAPSHOT" not found
[INFO] [creator] ===> DETECTING
[INFO] [creator] target distro name/version labels not found, reading /etc/os-release file
[INFO] [creator] 6 of 15 buildpacks participating
[INFO] [creator] paketo-buildpacks/ca-certificates 3.9.1
[INFO] [creator] paketo-buildpacks/bellsoft-liberica 11.0.5
[INFO] [creator] paketo-buildpacks/syft 2.8.0
[INFO] [creator] paketo-buildpacks/executable-jar 6.12.1
[INFO] [creator] paketo-buildpacks/spring-boot 5.32.1
[INFO] [creator] paketo-buildpacks/native-image 5.15.1
[INFO] [creator] ===> RESTORING
[INFO] [creator] ===> BUILDING
[INFO] [creator] target distro name/version labels not found, reading /etc/os-release file
[INFO] [creator]
[INFO] [creator] Paketo Buildpack for CA Certificates 3.9.1
[INFO] [creator] https://github.com/paketo-buildpacks/ca-certificates
[INFO] [creator] Build Configuration:
[INFO] [creator] $BP_EMBED_CERTS false Embed certificates into the image
[INFO] [creator] $BP_ENABLE_RUNTIME_CERT_BINDING true Deprecated: Enable/disable certificate helper layer to add certs at runtime
[INFO] [creator] $BP_RUNTIME_CERT_BINDING_DISABLED false Disable certificate helper layer to add certs at runtime
[INFO] [creator] Launch Helper: Contributing to layer
[INFO] [creator] Creating /layers/paketo-buildpacks_ca-certificates/helper/exec.d/ca-certificates-helper
[INFO] [creator]
[INFO] [creator] Paketo Buildpack for BellSoft Liberica 11.0.5
[INFO] [creator] https://github.com/paketo-buildpacks/bellsoft-liberica
[INFO] [creator] Build Configuration:
[INFO] [creator] $BP_JVM_JLINK_ARGS --no-man-pages --no-header-files --strip-debug --compress=1 configure custom link arguments (--output must be omitted)
[INFO] [creator] $BP_JVM_JLINK_ENABLED false enables running jlink tool to generate custom JRE
[INFO] [creator] $BP_JVM_TYPE JRE the JVM type - JDK or JRE
[INFO] [creator] $BP_JVM_VERSION 21 the Java version
[INFO] [creator] Launch Configuration:
[INFO] [creator] $BPL_DEBUG_ENABLED false enables Java remote debugging support
[INFO] [creator] $BPL_DEBUG_PORT 8000 configure the remote debugging port
[INFO] [creator] $BPL_DEBUG_SUSPEND false configure whether to suspend execution until a debugger has attached
[INFO] [creator] $BPL_HEAP_DUMP_PATH write heap dumps on error to this path
[INFO] [creator] $BPL_JAVA_NMT_ENABLED true enables Java Native Memory Tracking (NMT)
[INFO] [creator] $BPL_JAVA_NMT_LEVEL summary configure level of NMT, summary or detail
[INFO] [creator] $BPL_JFR_ARGS configure custom Java Flight Recording (JFR) arguments
[INFO] [creator] $BPL_JFR_ENABLED false enables Java Flight Recording (JFR)
[INFO] [creator] $BPL_JMX_ENABLED false enables Java Management Extensions (JMX)
[INFO] [creator] $BPL_JMX_PORT 5000 configure the JMX port
[INFO] [creator] $BPL_JVM_HEAD_ROOM 0 the headroom in memory calculation
[INFO] [creator] $BPL_JVM_LOADED_CLASS_COUNT 35% of classes the number of loaded classes in memory calculation
[INFO] [creator] $BPL_JVM_THREAD_COUNT 250 the number of threads in memory calculation
[INFO] [creator] $JAVA_TOOL_OPTIONS the JVM launch flags
[INFO] [creator] Using Java version 17 extracted from MANIFEST.MF
[INFO] [creator] BellSoft Liberica NIK 17.0.14: Contributing to layer
[INFO] [creator] Downloading from https://github.com/bell-sw/LibericaNIK/releases/download/23.0.7+1-17.0.14+10/bellsoft-liberica-vm-core-openjdk17.0.14+10-23.0.7+1-linux-aarch64.tar.gz
[INFO] [creator] Verifying checksum
[INFO] [creator] Expanding to /layers/paketo-buildpacks_bellsoft-liberica/native-image-svm
[INFO] [creator] Adding 146 container CA certificates to JVM truststore
[INFO] [creator] Writing env.build/JAVA_HOME.override
[INFO] [creator] Writing env.build/JDK_HOME.override
[INFO] [creator]
[INFO] [creator] Paketo Buildpack for Syft 2.8.0
[INFO] [creator] https://github.com/paketo-buildpacks/syft
[INFO] [creator] Downloading from https://github.com/anchore/syft/releases/download/v1.20.0/syft_1.20.0_linux_arm64.tar.gz
[INFO] [creator] Verifying checksum
[INFO] [creator] Writing env.build/SYFT_CHECK_FOR_APP_UPDATE.default
[INFO] [creator]
[INFO] [creator] Paketo Buildpack for Executable JAR 6.12.1
[INFO] [creator] https://github.com/paketo-buildpacks/executable-jar
[INFO] [creator] Class Path: Contributing to layer
[INFO] [creator] Writing env/CLASSPATH.delim
[INFO] [creator] Writing env/CLASSPATH.prepend
[INFO] [creator] Process types:
[INFO] [creator] executable-jar: java org.springframework.boot.loader.launch.JarLauncher (direct)
[INFO] [creator] task: java org.springframework.boot.loader.launch.JarLauncher (direct)
[INFO] [creator] web: java org.springframework.boot.loader.launch.JarLauncher (direct)
[INFO] [creator]
[INFO] [creator] Paketo Buildpack for Spring Boot 5.32.1
[INFO] [creator] https://github.com/paketo-buildpacks/spring-boot
[INFO] [creator] Build Configuration:
[INFO] [creator] $BPL_JVM_CDS_ENABLED false whether to enable CDS optimizations at runtime
[INFO] [creator] $BPL_SPRING_AOT_ENABLED false whether to enable Spring AOT at runtime
[INFO] [creator] $BP_JVM_CDS_ENABLED false whether to enable CDS & perform JVM training run
[INFO] [creator] $BP_SPRING_AOT_ENABLED false whether to enable Spring AOT
[INFO] [creator] $BP_SPRING_CLOUD_BINDINGS_DISABLED false whether to contribute Spring Boot cloud bindings support
[INFO] [creator] $BP_SPRING_CLOUD_BINDINGS_VERSION 1 default version of Spring Cloud Bindings library to contribute
[INFO] [creator] Launch Configuration:
[INFO] [creator] $BPL_SPRING_CLOUD_BINDINGS_DISABLED false whether to auto-configure Spring Boot environment properties from bindings
[INFO] [creator] $BPL_SPRING_CLOUD_BINDINGS_ENABLED true Deprecated - whether to auto-configure Spring Boot environment properties from bindings
[INFO] [creator] Class Path: Contributing to layer
[INFO] [creator] Writing env.build/CLASSPATH.append
[INFO] [creator] Writing env.build/CLASSPATH.delim
[INFO] [creator] Image labels:
[INFO] [creator] org.opencontainers.image.title
[INFO] [creator] org.opencontainers.image.version
[INFO] [creator] org.springframework.boot.version
[INFO] [creator]
[INFO] [creator] Paketo Buildpack for Native Image 5.15.1
[INFO] [creator] https://github.com/paketo-buildpacks/native-image
[INFO] [creator] Build Configuration:
[INFO] [creator] $BP_BINARY_COMPRESSION_METHOD Compression mechanism used to reduce binary size. Options: `none` (default), `upx` or `gzexe`
[INFO] [creator] $BP_NATIVE_IMAGE enable native image build
[INFO] [creator] $BP_NATIVE_IMAGE_BUILD_ARGUMENTS arguments to pass to the native-image command
[INFO] [creator] $BP_NATIVE_IMAGE_BUILD_ARGUMENTS_FILE a file with arguments to pass to the native-image command
[INFO] [creator] $BP_NATIVE_IMAGE_BUILT_ARTIFACT the built application artifact explicitly, required if building from a JAR
[INFO] [creator] Native Image: Contributing to layer
[INFO] [creator] Executing native-image --no-fallback -H:+StaticExecutableWithDynamicLibC -H:Name=/layers/paketo-buildpacks_native-image/native-image/com.hancher.springboot3.graalvmnativeapp.GraalvmNativeAppApplication -cp /workspace:/workspace/BOOT-INF/classes:/workspace/BOOT-INF/lib/spring-boot-3.4.3.jar:/workspace/BOOT-INF/lib/spring-boot-autoconfigure-3.4.3.jar:/workspace/BOOT-INF/lib/logback-classic-1.5.16.jar:/workspace/BOOT-INF/lib/logback-core-1.5.16.jar:/workspace/BOOT-INF/lib/log4j-to-slf4j-2.24.3.jar:/workspace/BOOT-INF/lib/log4j-api-2.24.3.jar:/workspace/BOOT-INF/lib/jul-to-slf4j-2.0.16.jar:/workspace/BOOT-INF/lib/jakarta.annotation-api-2.1.1.jar:/workspace/BOOT-INF/lib/snakeyaml-2.3.jar:/workspace/BOOT-INF/lib/jackson-databind-2.18.2.jar:/workspace/BOOT-INF/lib/jackson-annotations-2.18.2.jar:/workspace/BOOT-INF/lib/jackson-core-2.18.2.jar:/workspace/BOOT-INF/lib/jackson-datatype-jdk8-2.18.2.jar:/workspace/BOOT-INF/lib/jackson-datatype-jsr310-2.18.2.jar:/workspace/BOOT-INF/lib/jackson-module-parameter-names-2.18.2.jar:/workspace/BOOT-INF/lib/tomcat-embed-core-10.1.36.jar:/workspace/BOOT-INF/lib/tomcat-embed-el-10.1.36.jar:/workspace/BOOT-INF/lib/tomcat-embed-websocket-10.1.36.jar:/workspace/BOOT-INF/lib/spring-web-6.2.3.jar:/workspace/BOOT-INF/lib/spring-beans-6.2.3.jar:/workspace/BOOT-INF/lib/micrometer-observation-1.14.4.jar:/workspace/BOOT-INF/lib/micrometer-commons-1.14.4.jar:/workspace/BOOT-INF/lib/spring-webmvc-6.2.3.jar:/workspace/BOOT-INF/lib/spring-aop-6.2.3.jar:/workspace/BOOT-INF/lib/spring-context-6.2.3.jar:/workspace/BOOT-INF/lib/spring-expression-6.2.3.jar:/workspace/BOOT-INF/lib/slf4j-api-2.0.16.jar:/workspace/BOOT-INF/lib/spring-core-6.2.3.jar:/workspace/BOOT-INF/lib/spring-jcl-6.2.3.jar:/workspace/BOOT-INF/lib/spring-boot-jarmode-tools-3.4.3.jar com.hancher.springboot3.graalvmnativeapp.GraalvmNativeAppApplication
[INFO] [creator] ================================================================================
[INFO] [creator] GraalVM Native Image: Generating 'com.hancher.springboot3.graalvmnativeapp.GraalvmNativeAppApplication' (static executable)...
[INFO] [creator] ================================================================================
[INFO] [creator] For detailed information and explanations on the build output, visit:
[INFO] [creator] https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md
[INFO] [creator] --------------------------------------------------------------------------------
[INFO] [creator] Warning: Method ch.qos.logback.core.FileAppender.valueOf(String) not found.
[INFO] [creator] Warning: Method ch.qos.logback.core.Layout.valueOf(String) not found.
[INFO] [creator] Warning: Method ch.qos.logback.core.rolling.RollingPolicy.valueOf(String) not found.
[INFO] [creator] Warning: Method ch.qos.logback.core.rolling.TriggeringPolicy.valueOf(String) not found.
[INFO] [creator] Warning: Method ch.qos.logback.core.spi.ContextAware.valueOf(String) not found.
[INFO] [creator] Warning: Could not resolve class jakarta.inject.Inject for reflection configuration. Reason: java.lang.ClassNotFoundException: jakarta.inject.Inject.
[INFO] [creator] Warning: Could not resolve class jakarta.inject.Provider for reflection configuration. Reason: java.lang.ClassNotFoundException: jakarta.inject.Provider.
[INFO] [creator] Warning: Could not resolve class jakarta.inject.Qualifier for reflection configuration. Reason: java.lang.ClassNotFoundException: jakarta.inject.Qualifier.
[INFO] [creator] Warning: Could not resolve class javax.inject.Inject for reflection configuration. Reason: java.lang.ClassNotFoundException: javax.inject.Inject.
[INFO] [creator] Warning: Could not resolve class javax.inject.Qualifier for reflection configuration. Reason: java.lang.ClassNotFoundException: javax.inject.Qualifier.
[INFO] [creator] Warning: Could not resolve class javax.money.MonetaryAmount for reflection configuration. Reason: java.lang.ClassNotFoundException: javax.money.MonetaryAmount.
[INFO] [creator] Warning: Could not resolve class kotlin.Metadata for reflection configuration. Reason: java.lang.ClassNotFoundException: kotlin.Metadata.
[INFO] [creator] Warning: Could not resolve class kotlin.reflect.full.KClasses for reflection configuration. Reason: java.lang.ClassNotFoundException: kotlin.reflect.full.KClasses.
[INFO] [creator] Warning: Could not resolve class org.eclipse.core.runtime.FileLocator for reflection configuration. Reason: java.lang.ClassNotFoundException: org.eclipse.core.runtime.FileLocator.
[INFO] [creator] Warning: Could not resolve class org.reactivestreams.Publisher for reflection configuration. Reason: java.lang.ClassNotFoundException: org.reactivestreams.Publisher.
[INFO] [creator] [1/8] Initializing... (5.0s @ 0.12GB)
[INFO] [creator] Java version: 17.0.14+10-LTS, vendor version: Liberica-NIK-23.0.7-1
[INFO] [creator] Graal compiler: optimization level: 2, target machine: armv8-a
[INFO] [creator] C compiler: gcc (linux, aarch64, 11.4.0)
[INFO] [creator] Garbage collector: Serial GC (max heap size: 80% of RAM)
[INFO] [creator] 1 user-specific feature(s)
[INFO] [creator] - org.springframework.aot.nativex.feature.PreComputeFieldFeature
[INFO] [creator] SLF4J(W): No SLF4J providers were found.
[INFO] [creator] SLF4J(W): Defaulting to no-operation (NOP) logger implementation
[INFO] [creator] SLF4J(W): See https://www.slf4j.org/codes.html#noProviders for further details.
[INFO] [creator] [2/8] Performing analysis... [*******] (69.2s @ 1.53GB)
[INFO] [creator] 16,540 (90.76%) of 18,224 types reachable
[INFO] [creator] 27,186 (67.63%) of 40,196 fields reachable
[INFO] [creator] 79,799 (63.18%) of 126,298 methods reachable
[INFO] [creator] 5,144 types, 355 fields, and 5,950 methods registered for reflection
[INFO] [creator] 64 types, 72 fields, and 55 methods registered for JNI access
[INFO] [creator] 4 native libraries: dl, pthread, rt, z
[INFO] [creator] [3/8] Building universe... (6.4s @ 1.98GB)
[INFO] [creator] [4/8] Parsing methods... [***] (7.4s @ 1.32GB)
[INFO] [creator] [5/8] Inlining methods... [***] (2.6s @ 1.02GB)
[INFO] [creator] [6/8] Compiling methods... [*******] (50.6s @ 1.30GB)
[INFO] [creator] [7/8] Layouting methods... [***] (5.8s @ 1.92GB)
[INFO] [creator] [8/8] Creating image... [***] (6.5s @ 2.08GB)
[INFO] [creator] 36.96MB (49.04%) for code area: 51,972 compilation units
[INFO] [creator] 35.49MB (47.09%) for image heap: 387,870 objects and 253 resources
[INFO] [creator] 2.92MB ( 3.88%) for other data
[INFO] [creator] 75.38MB in total
[INFO] [creator] --------------------------------------------------------------------------------
[INFO] [creator] Top 10 origins of code area: Top 10 object types in image heap:
[INFO] [creator] 12.67MB java.base 8.53MB byte[] for code metadata
[INFO] [creator] 4.24MB tomcat-embed-core-10.1.36.jar 3.95MB java.lang.Class
[INFO] [creator] 3.38MB java.xml 3.68MB java.lang.String
[INFO] [creator] 2.00MB jackson-databind-2.18.2.jar 3.30MB byte[] for java.lang.String
[INFO] [creator] 1.58MB spring-core-6.2.3.jar 3.23MB byte[] for general heap data
[INFO] [creator] 1.55MB spring-boot-3.4.3.jar 2.11MB byte[] for embedded resources
[INFO] [creator] 1.33MB svm.jar (Native Image) 1.39MB c.o.s.c.h.DynamicHubCompanion
[INFO] [creator] 983.63kB spring-web-6.2.3.jar 1.01MB byte[] for reflection metadata
[INFO] [creator] 910.71kB spring-beans-6.2.3.jar 740.64kB java.lang.String[]
[INFO] [creator] 876.46kB spring-webmvc-6.2.3.jar 597.34kB c.o.s.c.h.DynamicHu~onMetadata
[INFO] [creator] 7.22MB for 69 more packages 6.20MB for 3523 more object types
[INFO] [creator] --------------------------------------------------------------------------------
[INFO] [creator] Recommendations:
[INFO] [creator] HEAP: Set max heap for improved and more predictable memory usage.
[INFO] [creator] CPU: Enable more CPU features with '-march=native' for improved performance.
[INFO] [creator] --------------------------------------------------------------------------------
[INFO] [creator] 27.4s (17.7% of total time) in 132 GCs | Peak RSS: 3.50GB | CPU load: 2.69
[INFO] [creator] --------------------------------------------------------------------------------
[INFO] [creator] Produced artifacts:
[INFO] [creator] /layers/paketo-buildpacks_native-image/native-image/com.hancher.springboot3.graalvmnativeapp.GraalvmNativeAppApplication (executable)
[INFO] [creator] ================================================================================
[INFO] [creator] Finished generating 'com.hancher.springboot3.graalvmnativeapp.GraalvmNativeAppApplication' in 2m 34s.
[INFO] [creator] Removing bytecode
[INFO] [creator] Process types:
[INFO] [creator] native-image: ./com.hancher.springboot3.graalvmnativeapp.GraalvmNativeAppApplication (direct)
[INFO] [creator] task: ./com.hancher.springboot3.graalvmnativeapp.GraalvmNativeAppApplication (direct)
[INFO] [creator] web: ./com.hancher.springboot3.graalvmnativeapp.GraalvmNativeAppApplication (direct)
[INFO] [creator] ===> EXPORTING
[INFO] [creator] Adding layer 'paketo-buildpacks/ca-certificates:helper'
[INFO] [creator] Adding layer 'paketo-buildpacks/executable-jar:classpath'
[INFO] [creator] Adding layer 'buildpacksio/lifecycle:launch.sbom'
[INFO] [creator] Added 1/1 app layer(s)
[INFO] [creator] Adding layer 'buildpacksio/lifecycle:launcher'
[INFO] [creator] Adding layer 'buildpacksio/lifecycle:config'
[INFO] [creator] Adding layer 'buildpacksio/lifecycle:process-types'
[INFO] [creator] Adding label 'io.buildpacks.lifecycle.metadata'
[INFO] [creator] Adding label 'io.buildpacks.build.metadata'
[INFO] [creator] Adding label 'io.buildpacks.project.metadata'
[INFO] [creator] Adding label 'org.opencontainers.image.title'
[INFO] [creator] Adding label 'org.opencontainers.image.version'
[INFO] [creator] Adding label 'org.springframework.boot.version'
[INFO] [creator] Setting default process type 'web'
[INFO] [creator] Saving docker.io/library/graalvm-native-app:0.0.1-SNAPSHOT...
[INFO] [creator] *** Images (ede8e2b9d153):
[INFO] [creator] docker.io/library/graalvm-native-app:0.0.1-SNAPSHOT
[INFO] [creator] Adding cache layer 'paketo-buildpacks/bellsoft-liberica:native-image-svm'
[INFO] [creator] Adding cache layer 'paketo-buildpacks/syft:syft'
[INFO] [creator] Adding cache layer 'paketo-buildpacks/native-image:native-image'
[INFO] [creator] Adding cache layer 'buildpacksio/lifecycle:cache.sbom'
[INFO]
[INFO] Successfully built image 'docker.io/library/graalvm-native-app:0.0.1-SNAPSHOT'
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 06:41 min
[INFO] Finished at: 2025-03-08T00:22:42+08:00
[INFO] ------------------------------------------------------------------------

同打包java本地应用一样,打包docker 镜像也会比较慢,慢慢等待。

这里的打包慢,也是为了以后的app在启动和运行时速度快。

打包成功后,我们就可以在docker镜像里看到我们自己的应用镜像了

1
docker images

运行docker

1
docker run --rm -p 8080:8080 docker.io/library/graalvm-native-app:0.0.1-SNAPSHOT
  • –rm 容器结束后会自动删除

容器在0.08秒就启动起来了,是不是很快。

验证:

1
2
3
$ curl localhost:8080/hancher

Hello hancher

build-image VS build-image-no-fork

springboot 在打包docker镜像的时候,有build-imagebuild-image-no-fork两种模式,有什么区别呢?

build-image

这是 Spring Boot Maven 插件的默认目标,用于构建基于 Cloud Native Buildpacks 的 Docker 镜像

先调用 Paketo Buildpacks(默认构建工具)来分析项目、编译代码并生成镜像。
然后 打包 JAR 文件,再基于 JAR 生成镜像。

  • 执行过程:

    • 在独立的 Maven 进程(forked process)中运行。
    • 会启动一个新的 JVM 实例来执行构建任务,与当前的 Maven 构建进程分离。
  • 优点

    • 隔离性好,构建镜像的过程不会干扰主 Maven 进程。
    • 适合标准构建流程,尤其是 CI/CD 环境。
  • 缺点

    • 启动新进程会增加少量开销

build-image-no-fork

在当前 Maven 进程中构建 Docker 镜像,而不启动新的子进程,这样虽然会与其他操作冲突,但会更快,适合本地开发时使用(没有并发)。

  • 执行过程:

    • 在当前 JVM 实例内直接执行镜像构建任务,不进行 fork
  • 优点

    • 减少进程创建的开销,构建速度可能略快(尤其在小型项目中)
    • 更适合调试或本地开发,因为它与当前 Maven 上下文紧密耦合。
  • 缺点

    • 如果构建过程中出现问题(例如内存不足、异常),可能会影响整个 Maven 构建流程
    • 因为没有进程隔离的原因,可能导致资源竞争或配置冲突

主要区别

特性 build-image build-image-no-fork
执行进程 新建独立进程(forked) 当前进程(no fork)
隔离性 高,独立于主 Maven 进程 低,与主 Maven 进程共享环境
性能开销 略高(启动新 JVM) 略低(无需新进程)
适用场景 CI/CD、标准构建 本地调试、小型项目
稳定性 更稳定(隔离问题) 可能受主进程影响

你学废了吗?

参考

使用GraalVM打包系统可执行程序

github demo

springboot打包docker镜像配置


springboot可以把项目打包成app了,docker打包版
https://www.hancher.top/2025/03/08/spring-spring-native-image-docker/
作者
寒澈
发布于
2025年3月8日
许可协议