Search code examples
javagradledockerdockerfilegradlew

How to reduce my java/gradle docker image size?


I have a Docker file like the following:

FROM openjdk:8

ADD . /usr/share/app-name-tmp

WORKDIR /usr/share/app-name-tmp

RUN ./gradlew build \
    mv ./build/libs/app-name*.jar /usr/share/app-name/app-name.jar

WORKDIR /usr/share/app-name

RUN rm -rf /usr/share/app-name-tmp

EXPOSE 8080

RUN chmod +x ./docker-entry.sh

ENTRYPOINT [ "./docker-entry.sh" ]

The problem is that the final image size is 1.1GB, I know it happens because gradle downloads and stores all the dependencies. What is the best way to remove those unnecessary files and just keep the jar?


Solution

  • Each RUN instruction creates a new layer on top of the existing file system. So the new layer after RUN instruction that deletes you app-name-tmp directory just masks the previous layer containing the downloaded libraries. Hence your docker image still has that size from all the layers built.

    Remove the separate RUN rm -rf /usr/share/app-name-tmp instruction and include it in the same RUN instruction that does gradle build as shown below.

    RUN ./gradlew build \
        mv ./build/libs/app-name*.jar /usr/share/app-name/app-name.jar \
        rm -rf /usr/share/app-name-tmp/*
    

    So, your final Dockerfile would be

    FROM openjdk:8
    
    ADD . /usr/share/app-name-tmp
    WORKDIR /usr/share/app-name-tmp
    
    RUN ./gradlew build \
        mv ./build/libs/app-name*.jar /usr/share/app-name/app-name.jar \
        rm -rf /usr/share/app-name-tmp/*
    
    WORKDIR /usr/share/app-name
    
    EXPOSE 8080
    RUN chmod +x ./docker-entry.sh
    ENTRYPOINT [ "./docker-entry.sh" ]
    

    The image built will still add up size from the directory /usr/share/app-name-tmp.