Make tiny Docker images running Java code

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!


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.