I'm trying to put a Spring Boot application with war packaging into a docker image. The simplest way to get this can be using the following Dockerfile:
FROM adoptopenjdk/openjdk8:alpine-slim
VOLUME /tmp
COPY target/demo.war app.war
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.war"]
Following this approach I'm creating a big layer every time I change the project's source code. An alternative to this is to split the war into different docker layers as it is explained in this post: https://spring.io/blog/2018/11/08/spring-boot-in-a-container#a-better-dockerfile
However, I'm afraid this is only possible with jar packaging and not with war. Am I right?
Thanks in advance.
This is the way I get a multilayer docker image with a war applicaton.
First open the war file to find out which folders have to be copied to the image:
jar -xf youapp.war
In my project the war file is composed of these folders:
/WEB-INF
/META-INF
/resources
/org
Based on this, I created the following Dockerfile:
FROM openjdk:8-jdk-alpine AS builder
WORKDIR target/dependency
ARG APPWAR=target/*.war
COPY ${APPWAR} app.war
RUN jar -xf ./app.war
RUN mv WEB-INF/lib-provided lib-provided
RUN mv WEB-INF/lib lib
FROM openjdk:8-jre-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY --from=builder ${DEPENDENCY}/lib /app/WEB-INF/lib
COPY --from=builder ${DEPENDENCY}/lib-provided /app/WEB-INF/lib-provided
COPY --from=builder ${DEPENDENCY}/org /app/org
COPY --from=builder ${DEPENDENCY}/resources /app/resources
COPY --from=builder ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=builder ${DEPENDENCY}/WEB-INF /app/WEB-INF
ENTRYPOINT ["java","-cp","/app/WEB-INF/classes:/app/WEB-INF/lib/*:/app/WEB-INF/lib-provided/*","com.company.project.Application"]
I hope it is useful.