0

I've got a Springboot jar deployed as a webapp via Docker. Here is the basic outline of my Dockerfile.

#
# Build App
#
FROM maven:3.6.3-openjdk-15-slim AS build

# Copy Parent Project
COPY src /home/app/src
COPY pom.xml /home/app

RUN mvn -f /home/app/pom.xml clean package -DskipTests

#
# Deploy App
#
FROM openjdk:15-jdk-alpine
COPY --from=build /home/app/my-app/target/my-app-rest-0.0.1-SNAPSHOT.jar /usr/local/lib/app.jar
ENTRYPOINT exec java -Djava.security.egd=file:/dev/./urandom -jar /usr/local/lib/app.jar

I originally found a pattern similar to this Dockerfile around the internet and I thought I understood most of it, but one thing is eluding me: where are all of the dependency jars that are needed by my app.jar to run? My project is running and executing just fine, so those have to be somewhere in my container. But I've searched and searched but can't find any of the dependency jars or even the WEB-INF directory for my webapp. I know that my actual application jar is in /usr/local/lib/, but that's about all I can deduce.

Is there some default location where the dependency/webapp config would go? Is there something that I can add to my Dockerfile to define where it should go?

Austin Brown
  • 830
  • 12
  • 24

2 Answers2

1

Spring boot puts all your dependencies (jars) in fat executable jar, which is the one you are passing to the run stage, and the exact one you are running with the java command.

Since jar files are just compressed archives you can extract them using unzip an peek inside them:

docker cp <container-id>:/home/app/my-app/target/my-app-rest-0.0.1-SNAPSHOT.jar myjar.jar
unzip myjar.jar -d myjar
ls -al myjar/BOOT-INF/lib

And you'll get the list of all the jars you spring boot app depends on.

More information here and here

Iduoad
  • 895
  • 4
  • 15
  • Ahh, okay! I did not know that Spring Boot made a "fat" jar. That makes sense. Is there a way to configure Spring Boot to keep dependencies in a separate library folder? – Austin Brown Apr 29 '21 at 17:50
  • Yeah, of course you can! All of this is done using you build tool, be it maven or gradle. You can do this in a lot of different ways, depending on your usecase. One of them is here https://www.baeldung.com/spring-boot-multiple-modules You can also package you application another format e.g. package it as a war and run it in a separate application server. – Iduoad May 02 '21 at 04:53
0

Maven is used to build your .jar package, while you only need to put the .jar package into docker image and add java -jar ... as the entry point.

Note that Docker is strongly recommending programmers to separate applications into individual docker images. Even if you can have both Maven and .jar together, don't do that.

Is there some default location where the dependency/webapp config would go?

Yes. This is the Dockerfile I use at work. You run maven commands such as clean, package on your development machine, instead of inside a Dockerfile.

FROM openjdk:8-jdk-alpine
# You want to change JDK version.

ADD target/*.jar app.jar
# You have to place this Dockerfile in the SAME directory with the target folder. Then this Dockerfile pulls whatever jar you have under target, renames it to app.jar and adds it to the build.

EXPOSE 9001
# You want to change this to whatever port your java app listens on.

ENTRYPOINT ["java", "-jar", "/app.jar"]
# Typical command you use to run .jar package but this time, you use it as the entrypoint.

As soon as you have that .jar package, cd into the Dockerfile directory and docker build ..

justthink
  • 439
  • 3
  • 6
  • There was helpful information here, thank you. I think M. Iduoad answered my specific questions better, though, so I selected their answer. – Austin Brown Apr 29 '21 at 17:56