2025-03-17 11:03:59 - No Comments
Dockerize java applications with native code
I wanted to figure out how to run Java applications in a minimal Docker image. Using GraalVM this could become a reality with a size of 4 MB image.
The application could be found in one of my repositories but the main work force is the Dockerfile below.
This Dockerfile will download the native-image command from GraalVM and build the application as a native application of about 22 MB. Then it will compress it even further using the Ultimate Packer of eXecutables to make it even smaller about 600kb. Putting that into a scratch image with nothing more than the capability to run executables. This kind of image is usually used to bootstrap a new base image like Debian or similar so it's extremely small.
# Build in a container with Oracle GraalVM Native Image and MUSL
FROM container-registry.oracle.com/graalvm/native-image:23-muslib AS nativebuild
WORKDIR /build
# Install UPX
ARG UPX_VERSION=4.2.2
ARG UPX_ARCHIVE=upx-${UPX_VERSION}-amd64_linux.tar.xz
RUN microdnf -y install wget xz && \
wget -q https://github.com/upx/upx/releases/download/v${UPX_VERSION}/${UPX_ARCHIVE} && \
tar -xJf ${UPX_ARCHIVE} && \
rm -rf ${UPX_ARCHIVE} && \
mv upx-${UPX_VERSION}-amd64_linux/upx . && \
rm -rf upx-${UPX_VERSION}-amd64_linux
# Install Maven
ARG MAVEN_VERSION=3.9.9
ARG MAVEN_ARCHIVE=apache-maven-${MAVEN_VERSION}-bin.tar.gz
RUN wget -q https://dlcdn.apache.org/maven/maven-3/${MAVEN_VERSION}/binaries/${MAVEN_ARCHIVE} && \
tar -xzf ${MAVEN_ARCHIVE} && \
rm -rf ${MAVEN_ARCHIVE}
# Prepare application
COPY pom.xml .
ADD src src
RUN apache-maven-${MAVEN_VERSION}/bin/mvn clean package
# Build a native executable with native-image
RUN native-image -Os --static --libc=musl -jar target/notes-app-1.0-SNAPSHOT-jar-with-dependencies.jar -o notes
RUN ls -lh notes
# Compress the executable with UPX
RUN ./upx --lzma --best -o notes.upx notes
RUN ls -lh notes.upx
# Copy the compressed executable into a scratch container
FROM scratch
COPY --from=nativebuild /build/notes.upx /notes.upx
COPY static /static
ENTRYPOINT ["/notes.upx"]
Be the first to leave a comment!