1

I have a Java Spring Boot web application that I'd like to containerize using Docker. I'm having trouble getting the mvn install command to work during the Docker build process because my project depends on some other Maven projects I've written that are installed in my local /.m2 folder but aren't available in the Maven central repository. I'd like to avoid adding these local projects to the public Maven central repository because they exist specifically to support this Spring Boot application and I'd like to keep them private.

If I wasn't using Docker, I could get around this problem by building a JAR with dependencies then deploying that .jar file. Is there any way for me to include these local dependencies in my Docker build process?

Here's the simple Dockerfile I'm trying to run:

# Step 1: Build with Maven
FROM maven:3.5-jdk-8-alpine

COPY . /usr/src/myapp
WORKDIR /usr/src/myapp

RUN mvn clean install


# Step 2: Run jar file with Java
FROM openjdk:8-alpine

WORKDIR /usr/src/myapp

COPY --from=0 /usr/src/myapp/target/myapp-1.0-SNAPSHOT.jar ./myapp.jar

ENTRYPOINT ["java", "-jar", "myapp.jar"]

I run this build command:

docker build -t myspringapp .

And it errors with the following message:

[ERROR] Failed to execute goal on project server: Could not resolve dependencies for project 
com.website:myapp:jar:1.0-SNAPSHOT: The following artifacts could not be resolved: 
com.website:dependency1:jar:0.1.0, com.website:dependency2:jar:0.1.0, 
com.website:dependency3:jar:0.1.0: 
Could not find artifact com.website:dependency1:jar:0.1.0 in central 
(https://repo.maven.apache.org/maven2) -> [Help 1]

As an alternative question, can I just run the mvn clean install command on my development machine to produce the jar file then skip the whole Maven build part of the Docker image? Will my container still be able to replicate itself in an auto-scaling scenario? Do I lose anything by building the project separately from its Docker image/container?

Miles Henrichs
  • 2,300
  • 3
  • 20
  • 23
  • You have not told us **anything** about your Docker build process, but I would ***guess*** the answer is **yes**. That doesn't help you though, so perhaps what you are really asking is how can I deploy my application in Docker. And that involves building your application and then adding it to your dockerfile. And then building your docker image. And then (if you so desire) copy it to your private docker registry. Maven has nothing to do with it (beyond that first part, build your application). – Elliott Frisch Mar 21 '20 at 02:32
  • I added my Dockerfile and the results of the docker build execution. You're correct in that Maven doesn't cause a problem beyond the build step. If possible, however, I'd like to build with Maven as part of my Docker build process, but I'm unable to due to my use of locally installed Maven projects. I'm wondering if there's a way to include these local projects in the Docker image. – Miles Henrichs Mar 21 '20 at 05:10
  • You can use nexus as local maven repository. Look at this https://stackoverflow.com/a/59676104/6831257 – GolamMazid Sajib Mar 21 '20 at 05:24
  • what i see is you need to create `/usr/src/myapp` folder first inside `dockerfile` – Donald Wu Mar 21 '20 at 05:29
  • @MilesHenrichs and you can try to use `RUN cp /usr/src/myapp/target/myapp-1.0-SNAPSHOT.jar ./myapp.jar` ? – Donald Wu Mar 21 '20 at 05:31
  • @DonaldWu the issues I'm having aren't related to the contents of my Dockerfile. The error is happening on the `RUN mvn clean install` line because my project depends on local Maven projects that aren't accessible through Maven central. – Miles Henrichs Mar 21 '20 at 05:37
  • @MilesHenrichs is this similar? https://stackoverflow.com/questions/40522967/maven-install-file-not-effective-in-gitlab-docker-could-not-resolve-dependenci – Donald Wu Mar 21 '20 at 05:39
  • Build your program with maven. Remove all of the build steps from your docker file. Build your program with maven (and ignore docker until you build your program). Once your program is built, use Donald Wu's suggestion (or **any** other mechanism, like git or your maven nexus) to get the **built** artifact and put the **built** artifact in your docker file. Then the *following artifacts could not be resolved* error "magically" goes away. In short, *Do I lose anything by building the project separately from its Docker image/container?*, **no**. – Elliott Frisch Mar 21 '20 at 06:52

1 Answers1

1

Easiest thing to do would be to just put your .m2 directory in the Docker build context, and make sure the build stage of the Dockerfile does a COPY of .m2 to wherever the base maven image is expecting it to be. That way, the build stage doesn't need to download your private JAR files.

To answer your alternative question, yes. It's not very 12-factor, but it's definitely doable to do the JAR build outside of the Docker ecosystem, then just COPY the pre-built JAR file into the image.

wmorrell
  • 4,988
  • 4
  • 27
  • 37
  • Thanks for mentioning 12-factor! I'd never heard of it before, I just looked it up and I'm learning quite a bit from it. Based on what I've seen, it seems like it's pretty common to build a Spring application JAR outside of the Docker process then just `COPY` it in, as you stated. This might be the best option for my scenario. – Miles Henrichs Mar 21 '20 at 21:28