@nicolas_frankel
A Hitchhiker's Tour to
Containerizing a (Java)
Application
Nicolas Fränkel
@nicolas_frankel
Me, myself and I
 Former developer, team lead, architect,
blah-blah
 Developer Advocate
 Curious about Containerization, Docker
& Kubernetes
@nicolas_frankel
Hazelcast
HAZELCAST IMDG is an operational,
in-memory, distributed computing
platform that manages data using
in-memory storage and performs
execution for breakthrough
and scale.
HAZELCAST JET is the ultra
fast, application embeddable,
3rd generation stream
processing engine for low
latency batch and stream
processing.
@nicolas_frankel
Containerizing a Python app
FROM python:3
ADD requirements.txt .
RUN pip install
ADD script.py .
CMD ["python", "./script.py"]
@nicolas_frankel
Containerizing a Node.js app
FROM node:12
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD ["node", "server.js"]
@nicolas_frankel
Scripting languages
 There’s no final binary/intermediate
bytecode
• No compile phase
• Just download the dependencies
 WYSIWYR
• « What You See Is What You Run »
@nicolas_frankel
Building a Java app
 Download the dependencies
 Compile the sources to bytecode
 Build the JAR
• Just a ZIP with a standard structure
@nicolas_frankel
Containerizing a Java app
FROM maven:3.5-jdk-8-alpine:build
RUN mvn package
CMD [
"java",
"-jar",
"target/foo-x.y.z.jar”
]
@nicolas_frankel
Issues
Embeds a JDK
Increased size
Can compile Java code 😱 😱 😱
Version handling
No layering
@nicolas_frankel
Alternative
Create the JAR outside of Docker 🤔
@nicolas_frankel
Sampleapplication
@nicolas_frankel
Proposal 1: Multistage builds
 COPY --from=0
• COPY --from=name
 Pretty widespread
 Not compatible with Skaffold
@nicolas_frankel
Proposal 2: Jib
 Standard Maven plugin
 Pushes to a remote Docker repo
• Or to the local Docker daemon
 Lots of configuration options
• e.g. parent image
 Runs the « exploded » JAR
@nicolas_frankel
Benefits
 No Dockerfile
 Automatic version handling from the POM
 Layers
1. Dependencies
2. Resources
3. Compiled code
@nicolas_frankel
Are those layers enough?
 What about SNAPSHOT dependencies?
@nicolas_frankel
Solution 3: Layer-aware multi-stage build
 Spring Boot is able to create a Docker-
friendly layered output
@nicolas_frankel
Benefits
 Layers
1. Dependencies
2. Resources
3. Snapshot dependencies
4. Compiled code
 Customizable
@nicolas_frankel
Downsides
 Back to Dockerfile!
@nicolas_frankel
Solution 4: Buildpack
 External tool able to understand how to
build your project
 Based on the Heroku buildpack design
 Project backed by CNCF
• Joined by VMWare Tanzu (Spring)
 Lots of configuration options
@nicolas_frankel
Benefits
 No Dockerfile
 Skaffold friendly
 Previous 4 layers
@nicolas_frankel
Downsides
 No version sync between the POM and the
Docker image
 No choice of the parent image 😕
 Run the whole build process even without
changes
 Doesn’t cache the images used during the
build
• e.g. the JDK
@nicolas_frankel
Solution 5: Spring Boot Maven plugin
 Uses the CNCF buildpack from inside
the Maven lifecycle
 Lots of configuration options
@nicolas_frankel
Benefits
 No Dockerfile
 Layered
 POM and Docker image version are in
sync
@nicolas_frankel
Downsides
 No choice of the parent image
@nicolas_frankel
Flattening layers
 docker-squash
 From 1.0:
• 0.06% gain
 From 5.0:
• 0.95% gain
@nicolas_frankel
Recap
 Sync version between the POM and the
image
 Organize layers for faster development
 Squash might not be that useful
@nicolas_frankel
Thanks for your attention!
 https://blog.frankel.ch/
 @nicolas_frankel
 http://bit.ly/containerinzing-apps

OSCONF Jaipur - A Hitchhiker's Tour to Containerizing a Java application

Editor's Notes

  • #13 skinparam dpi 150 actor " " as user node Docker { node JVM as jvm1 { package "spring-in-docker.jar" as app { component "hazelcast-client.jar" as jar } } } node JVM as jvm2 { component Hazelcast as hz } () " " as api () REST as rest app -up- rest hz -up- api jar ..> api user .right.> rest