Skip to content

Commit a897b33

Browse files
committed
Adds section about Buildpacks
1 parent 76bbb5b commit a897b33

File tree

1 file changed

+93
-2
lines changed

1 file changed

+93
-2
lines changed

content/post/dockerize-spring-boot.md

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,97 @@ So even a single change could cause the jar to be re-built and copied again. We
133133

134134
Can't we leverage other people's work rather than trying to come up with most optimal `Dockerfile` ourself?
135135

136-
## Use Buildpack
136+
## Use Buildpacks
137137

138-
TBD
138+
Many of the problems that I mentioned previously comes from that the fact that we wrote our `Dockerfile` manually. So let's look another approach which does not need any Dockerfile at all.
139+
140+
[Buildpacks](https://buildpacks.io/) transform the source code into containers without Dockerfiles. There are multiple projects that implements the Cloud Native Buildpacks (CNBs) [spec](https://github.com/buildpacks/spec) and probably best two options for java application today is:
141+
[Paketo](https://paketo.io/) and [Jib](https://github.com/GoogleContainerTools/jib).
142+
143+
### Paketo
144+
145+
We can use paketo by executing the following gradle (or maven) task:
146+
147+
```gradle
148+
./gradlew bootBuildImage
149+
```
150+
151+
The task will look at your files, configurations and create a docker image based on the result of the analyses. It's output is really user friendly and show all the parameters that it used for building the image.
152+
153+
```bash
154+
> Task :bootBuildImage
155+
Building image 'docker.io/library/dockerize-spring-boot:0.0.1-SNAPSHOT'
156+
157+
> Pulling builder image 'docker.io/paketobuildpacks/builder-jammy-java-tiny:latest'
158+
> Pulled builder image 'paketobuildpacks/builder-jammy-java-tiny@sha256:c5c53'
159+
> Pulling run image 'docker.io/paketobuildpacks/run-jammy-tiny:latest' for platform 'linux/amd64'
160+
> Pulled run image 'paketobuildpacks/run-jammy-tiny@sha256:0c5ac'
161+
> Executing lifecycle version v0.20.6
162+
> Using build cache volume 'pack-cache-7b0feb92a365.build'
163+
164+
> Running creator
165+
[creator] ===> ANALYZING
166+
[creator] Image with name "docker.io/library/dockerize-spring-boot:0.0.1-SNAPSHOT" not found
167+
[creator] ===> DETECTING
168+
[creator] ...
169+
[creator] ===> RESTORING
170+
[creator] ===> BUILDING
171+
[creator] ...
172+
[creator] Paketo Buildpack for Spring Boot 5.32.1
173+
[creator] https://github.com/paketo-buildpacks/spring-boot
174+
[creator] Build Configuration:
175+
[creator] $BPL_JVM_CDS_ENABLED false whether to enable CDS optimizations at runtime
176+
[creator] $BPL_SPRING_AOT_ENABLED false whether to enable Spring AOT at runtime
177+
[creator] $BP_JVM_CDS_ENABLED false whether to enable CDS & perform JVM training run
178+
[creator] $BP_SPRING_AOT_ENABLED false whether to enable Spring AOT
179+
[creator] $BP_SPRING_CLOUD_BINDINGS_DISABLED false whether to contribute Spring Boot cloud bindings support
180+
[creator] $BP_SPRING_CLOUD_BINDINGS_VERSION 1 default version of Spring Cloud Bindings library to contribute
181+
[creator] Launch Configuration:
182+
[creator] $BPL_SPRING_CLOUD_BINDINGS_DISABLED false whether to auto-configure Spring Boot environment properties from bindings
183+
[creator] $BPL_SPRING_CLOUD_BINDINGS_ENABLED true Deprecated - whether to auto-configure Spring Boot environment properties from bindings
184+
[creator] Creating slices from layers index
185+
[creator] dependencies (19.5 MB)
186+
[creator] spring-boot-loader (458.8 KB)
187+
[creator] snapshot-dependencies (0.0 B)
188+
[creator] application (35.9 KB)
189+
[creator] Spring Cloud Bindings 2.0.4: Contributing to layer
190+
[creator] Downloading from https://repo1.maven.org/maven2/org/springframework/cloud/spring-cloud-bindings/2.0.4/spring-cloud-bindings-2.0.4.jar
191+
[creator] Verifying checksum
192+
[creator] Copying to /layers/paketo-buildpacks_spring-boot/spring-cloud-bindings
193+
[creator] Web Application Type: Contributing to layer
194+
[creator] Servlet web application detected
195+
[creator] Writing env.launch/BPL_JVM_THREAD_COUNT.default
196+
[creator] Launch Helper: Contributing to layer
197+
[creator] Creating /layers/paketo-buildpacks_spring-boot/helper/exec.d/spring-cloud-bindings
198+
[creator] 4 application slices
199+
[creator] Image labels:
200+
[creator] org.opencontainers.image.title
201+
[creator] org.opencontainers.image.version
202+
[creator] org.springframework.boot.version
203+
[creator] ===> EXPORTING
204+
[creator] Adding layer 'paketo-buildpacks/...
205+
[creator] ...
206+
207+
Successfully built image 'docker.io/library/dockerize-spring-boot:0.0.1-SNAPSHOT'
208+
209+
BUILD SUCCESSFUL in 1m 57s
210+
```
211+
212+
Let's run and test our the newly created images as before:
213+
214+
```sh
215+
$ docker run -it -p 8080:8080 --rm dockerize-spring-boot:0.0.1-SNAPSHOT
216+
$ curl http://localhost:8080/ping
217+
> Pong!
218+
```
219+
220+
This already gives us a solid ground to build upon for production and uses all the best practices almost for free. For example we already could see two benefits:
221+
222+
- The size of the created docker image from the "manual" `Dockerfile` is **468MB** while the image created by paketo with default settings is **265MB**.
223+
- The docker layers are cached. When only the java source code is changed, we can see the following message: *Reused 4/5 app layer(s)*. So we (Paketo) can optimize our build and rebuild only what's actually necesseary.
224+
225+
For more information please have a look on the Spring doc [Packaging OCI Images](https://docs.spring.io/spring-boot/gradle-plugin/packaging-oci-image.html).
226+
227+
### Jib
228+
229+
*Coming soon...*

0 commit comments

Comments
 (0)