164

I am new to Docker, and don't know how to run a java project with maven even though I have read many documents and tried many methods.

  1. Should I build the image using Dockerfile?
  2. What is the commands like when it is to run the maven project in the host with Dockerfile?
Nicholas K
  • 15,148
  • 7
  • 31
  • 57
Yashon Lin
  • 1,845
  • 2
  • 13
  • 10

7 Answers7

260

Working example.

This is not a spring boot tutorial. It's the updated answer to a question on how to run a Maven build within a Docker container.

Question originally posted 4 years ago.

1. Generate an application

Use the spring initializer to generate a demo app

https://start.spring.io/

enter image description here

Extract the zip archive locally

2. Create a Dockerfile

#
# Build stage
#
FROM maven:3.6.0-jdk-11-slim AS build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package

#
# Package stage
#
FROM openjdk:11-jre-slim
COPY --from=build /home/app/target/demo-0.0.1-SNAPSHOT.jar /usr/local/lib/demo.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/usr/local/lib/demo.jar"]

Note

  • This example uses a multi-stage build. The first stage is used to build the code. The second stage only contains the built jar and a JRE to run it (note how jar is copied between stages).

3. Build the image

docker build -t demo .

4. Run the image

$ docker run --rm -it demo:latest

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.3.RELEASE)

2019-02-22 17:18:57.835  INFO 1 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication v0.0.1-SNAPSHOT on f4e67677c9a9 with PID 1 (/usr/local/bin/demo.jar started by root in /)
2019-02-22 17:18:57.837  INFO 1 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2019-02-22 17:18:58.294  INFO 1 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 0.711 seconds (JVM running for 1.035)

Misc

Read the Docker hub documentation on how the Maven build can be optimized to use a local repository to cache jars.

Update (2019-02-07)

This question is now 4 years old and in that time it's fair to say building application using Docker has undergone significant change.

Option 1: Multi-stage build

This new style enables you to create more light-weight images that don't encapsulate your build tools and source code.

The example here again uses the official maven base image to run first stage of the build using a desired version of Maven. The second part of the file defines how the built jar is assembled into the final output image.

FROM maven:3.5-jdk-8 AS build  
COPY src /usr/src/app/src  
COPY pom.xml /usr/src/app  
RUN mvn -f /usr/src/app/pom.xml clean package

FROM gcr.io/distroless/java  
COPY --from=build /usr/src/app/target/helloworld-1.0.0-SNAPSHOT.jar /usr/app/helloworld-1.0.0-SNAPSHOT.jar  
EXPOSE 8080  
ENTRYPOINT ["java","-jar","/usr/app/helloworld-1.0.0-SNAPSHOT.jar"]  

Note:

  • I'm using Google's distroless base image, which strives to provide just enough run-time for a java app.

Option 2: Jib

I haven't used this approach but seems worthy of investigation as it enables you to build images without having to create nasty things like Dockerfiles :-)

https://github.com/GoogleContainerTools/jib

The project has a Maven plugin which integrates the packaging of your code directly into your Maven workflow.


Original answer (Included for completeness, but written ages ago)

Try using the new official images, there's one for Maven

https://registry.hub.docker.com/_/maven/

The image can be used to run Maven at build time to create a compiled application or, as in the following examples, to run a Maven build within a container.

Example 1 - Maven running within a container

The following command runs your Maven build inside a container:

docker run -it --rm \
       -v "$(pwd)":/opt/maven \
       -w /opt/maven \
       maven:3.2-jdk-7 \
       mvn clean install

Notes:

  • The neat thing about this approach is that all software is installed and running within the container. Only need docker on the host machine.
  • See Dockerfile for this version

Example 2 - Use Nexus to cache files

Run the Nexus container

docker run -d -p 8081:8081 --name nexus sonatype/nexus

Create a "settings.xml" file:

<settings>
  <mirrors>
    <mirror>
      <id>nexus</id>
      <mirrorOf>*</mirrorOf>
      <url>http://nexus:8081/content/groups/public/</url>
    </mirror>
  </mirrors>
</settings>

Now run Maven linking to the nexus container, so that dependencies will be cached

docker run -it --rm \
       -v "$(pwd)":/opt/maven \
       -w /opt/maven \
       --link nexus:nexus \
       maven:3.2-jdk-7 \
       mvn -s settings.xml clean install

Notes:

  • An advantage of running Nexus in the background is that other 3rd party repositories can be managed via the admin URL transparently to the Maven builds running in local containers.
Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
  • can this be used to replace the maven central for a gradle build? as stated in https://support.sonatype.com/entries/21596297-How-do-I-configure-my-Gradle-build-to-download-artifacts-from-Nexus- I replaced `mavenCentral()` in my gradle dependencies with `maven {url "http://nexus:8081..."` and are now just getting resolution problems. – mohamnag Jun 24 '15 at 14:18
  • @mohamnag Correct, the Maven "settings" file above does exactly that, redirecting all Maven Central requests to the local nexus repository. You need to outline what sort of resolution problems you are having. Could be anything... For example, have you setup the Docker link, so that the "nexus" host is properly resolved? – Mark O'Connor Jun 25 '15 at 19:14
  • I turned out that every thing was ok, but nexus either needed time to build the index or something else caused the trouble. I also tried to trigger an index update therefore I'm not sure which case fixed the problem. Thanks however. – mohamnag Jun 25 '15 at 19:36
  • Nexus 3 is now available as a docker container too. Use "sonatype/nexus3" – Thorbjørn Ravn Andersen Nov 08 '17 at 10:31
  • The new multibuild facility in Docker CE makes it easy to first build the application and then copy the result into the final container, instead of running the application in the Maven container. – Thorbjørn Ravn Andersen Nov 27 '17 at 09:33
  • The `--link` flag is obsolete. Use `--net=host` instead, and in `settings.xml` use `http://localhost:8081/nexus/content/groups/public`. – avandeursen Mar 31 '18 at 15:05
  • 1
    @avandeursen You're correct that the --link parameter is deprecated (Answer over 3 years old). However the more correct solution (in my opinion) is to create a docker network and run both containers on it. That way you can leverage the native DNS feature in Docker and continue to refer to the nexus container by name. Will update the example later – Mark O'Connor Apr 06 '18 at 15:37
  • I am threatening a downvote until you include a Dockerfile example! :) – Alexander Mills Jan 27 '19 at 06:18
  • @AlexanderMills I was unable to delete the answer, so instead revised to discuss some of the more modern techniques for build Java containers. I hope this helps you – Mark O'Connor Feb 07 '19 at 21:54
  • Tried solution from Update (2019-02-07)-Option 1: Multi-stage build ..Made change to Dockerfile. Then ran command `docker build . -t helloworld:v1` I can see image getting built. However, when I run command to start container: `docker run -p 8080:8080 -n helloworld-app -d helloworld:v1` container starts and exits with error in log: `Exception in thread "main" java.lang.ClassNotFoundException: com.example.HelloWorldApplication at java.net.URLClassLoader.findClass(URLClassLoader.java:382)` – Shivraj Feb 17 '19 at 16:29
  • Some addition to my earlier comment. Please review this post for more details: https://stackoverflow.com/questions/54727866/google-cloud-platform-pipeline-container-builder-issue-building-docker-image-usi – Shivraj Feb 17 '19 at 17:06
  • @Shivraj I have updated my answer above with a working example. I have also responded to you separate question where I think the problem is related to file paths within the Dockerfile. – Mark O'Connor Feb 22 '19 at 18:14
  • As for the Dockerfile, I would suggest swapping the two `COPY` commands in the build stage in order to allow Docker to cache the dependencies installation (they are less likely to change than what’s in `src/`). The target folder will need a trailing slash in this case (`/usr/src/app/`). – jotaen Sep 25 '20 at 08:14
53

There may be many ways.. But I implemented by following two ways

Given example is of maven project.

1. Using Dockerfile in maven project

Use the following file structure:

Demo
└── src
|    ├── main
|    │   ├── java
|    │       └── org
|    │           └── demo
|    │               └── Application.java
|    │   
|    └── test
|
├──── Dockerfile
├──── pom.xml

And update the Dockerfile as:

FROM java:8
EXPOSE 8080
ADD /target/demo.jar demo.jar
ENTRYPOINT ["java","-jar","demo.jar"]

Navigate to the project folder and type following command you will be ab le to create image and run that image:

$ mvn clean
$ mvn install
$ docker build -f Dockerfile -t springdemo .
$ docker run -p 8080:8080 -t springdemo

Get video at Spring Boot with Docker

2. Using Maven plugins

Add given maven plugin in pom.xml

<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>0.4.5</version>
        <configuration>
            <imageName>springdocker</imageName>
            <baseImage>java</baseImage>
            <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
            <resources>
                <resource>
                    <targetPath>/</targetPath>
                    <directory>${project.build.directory}</directory>
                    <include>${project.build.finalName}.jar</include>
                </resource>
            </resources>
        </configuration>
    </plugin>

Navigate to the project folder and type following command you will be able to create image and run that image:

$ mvn clean package docker:build
$ docker images
$ docker run -p 8080:8080 -t <image name>

In first example we are creating Dockerfile and providing base image and adding jar an so, after doing that we will run docker command to build an image with specific name and then run that image..

Whereas in second example we are using maven plugin in which we providing baseImage and imageName so we don't need to create Dockerfile here.. after packaging maven project we will get the docker image and we just need to run that image..

Sawny
  • 1,404
  • 2
  • 14
  • 31
Riddhi Gohil
  • 1,758
  • 17
  • 17
  • Rather than modifying the entrypoint to specify the artifact name you could use approach like in here: https://www.alooma.com/blog/building-dockers - utilize maven-dependency-plugin to use a common name. No need to put a versioned jar in docker container as the container itself is versioned. – kboom Aug 19 '17 at 12:32
31

Here is my contribution.
I will not try to list all tools/libraries/plugins that exist to take advantage of Docker with Maven. Some answers have already done it.
instead of, I will focus on applications typology and the Dockerfile way.
Dockerfile is really a simple and important concept of Docker (all known/public images rely on that) and I think that trying to avoid understanding and using Dockerfiles is not necessarily the better way to enter in the Docker world.

Dockerizing an application depends on the application itself and the goal to reach

1) For applications that we want to go on to run them on installed/standalone Java server (Tomcat, JBoss, etc...)

The road is harder and that is not the ideal target because that adds complexity (we have to manage/maintain the server) and it is less scalable and less fast than embedded servers in terms of build/deploy/undeploy.
But for legacy applications, that may be considered as a first step.
Generally, the idea here is to define a Docker image that will contain the application server. You could have your own Tomcat, JBoss or Weblogic base Dockerfile that setup and configure the server.
About the application(s) to deploy on the server, there is not really a standard way.
A possible approach is defining a Dockerfile by application or set of applications to deploy together. The Dockerfile would have as base image the application server Dockerfile created earlier.
That application Dockerfile would have as objective to retrieve the component (JARs/WARs/EARs) from Git or from a Maven repository manager for example and to deploy/install it/them properly on the application server.
For huge applications (millions of line of codes) with a lot of legacy stuffs, and so hard to migrate to a full spring boot embedded solution, that is really a nice improvement.
I will not detail more that approach since that is for minor use cases of Docker but I wanted to expose the overall idea of that approach because I think that for developers facing to these complex cases, it is great to know that some doors are opened to integrate Docker.

2) For applications that embed/bootstrap the server themselves (Spring Boot with server embedded : Tomcat, Netty, Jetty...)

That is the ideal target with Docker. I specified Spring Boot because that is a really nice framework to do that and that has also a very high level of maintainability but in theory we could use any other Java way to achieve that.
Generally, the idea here is to define a Docker image per application to deploy.
The docker images for the applications produce a JAR or a set of JAR/classes/configuration files and these start a JVM with the application (java command) when we create and start a container from these images.
For new applications or applications not too complex to migrate, that way has to be favored over standalone servers because that is the standard way and the most efficient way of using containers.
I will detail that approach.

Dockerizing a maven application

1) Without Spring Boot

The idea is to create a fat jar with Maven (the maven assembly plugin and the maven shade plugin help for that) that contains both the compiled classes of the application and needed maven dependencies.
Then we can identify two cases :

  • if the application is a desktop or autonomous application (that doesn't need to be deployed on a server) : we could specify as CMD/ENTRYPOINT in the Dockerfile the java execution of the application : java -cp .:/fooPath/* -jar myJar

  • if the application is a server application, for example Tomcat, the idea is the same : to get a fat jar of the application and to run a JVM in the CMD/ENTRYPOINT. But here with an important difference : we need to include some logic and specific libraries (org.apache.tomcat.embed libraries and some others) that starts the embedded server when the main application is started.
    We have a comprehensive guide on the heroku website.
    For the first case (autonomous application), that is a straight and efficient way to use Docker.
    For the second case (server application), that works but that is not straight, may be error prone and is not a very extensible model because you don't place your application in the frame of a mature framework such as Spring Boot that does many of these things for you and also provides a high level of extension.
    But that has a advantage : you have a high level of freedom because you use directly the embedded Tomcat API.

2) With Spring Boot

At last, here we go.
That is both simple, efficient and very well documented.
There are really several approaches to make a Maven/Spring Boot application to run on Docker.
Exposing all of them would be long and maybe boring.
The best choice depends on your requirement.
But whatever the way, the build strategy in terms of docker layers looks like the same.
We want to use a multi stage build : one relying on Maven for the dependency resolution and for build and another one relying on JDK or JRE to start the application.

Build stage (Maven image) :

  • pom copy to the image
  • dependencies and plugins downloads.
    About that, mvn dependency:resolve-plugins chained to mvn dependency:resolve may do the job but not always.
    Why ? Because these plugins and the package execution to package the fat jar may rely on different artifacts/plugins and even for a same artifact/plugin, these may still pull a different version. So a safer approach while potentially slower is resolving dependencies by executing exactly the mvn command used to package the application (which will pull exactly dependencies that you are need) but by skipping the source compilation and by deleting the target folder to make the processing faster and to prevent any undesirable layer change detection for that step.
  • source code copy to the image
  • package the application

Run stage (JDK or JRE image) :

  • copy the jar from the previous stage
  • entrypoint/cmd : run the application

Here two examples.

a) A simple way without cache for downloaded maven dependencies

Dockerfile :

########Maven build stage########
FROM maven:3.6-jdk-11 as maven_build
WORKDIR /app

#copy pom
COPY pom.xml .

#resolve maven dependencies
RUN mvn clean package -Dmaven.test.skip -Dmaven.main.skip -Dspring-boot.repackage.skip && rm -r target/

#copy source
COPY src ./src

# build the app (no dependency download here)
RUN mvn clean package  -Dmaven.test.skip

# split the built app into multiple layers to improve layer rebuild
RUN mkdir -p target/docker-packaging && cd target/docker-packaging && jar -xf ../my-app*.jar

########JRE run stage########
FROM openjdk:11.0-jre
WORKDIR /app

#copy built app layer by layer
ARG DOCKER_PACKAGING_DIR=/app/target/docker-packaging
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/lib /app/lib
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/classes /app/classes
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/META-INF /app/META-INF

#run the app
CMD java -cp .:classes:lib/* \
         -Djava.security.egd=file:/dev/./urandom \
         foo.bar.MySpringBootApplication

Drawback of that solution ? Any changes in the pom.xml means re-creates the whole layer that download and stores the maven dependencies. That is generally not acceptable for applications with many dependencies (and Spring Boot pulls many dependencies), overall if you don't use a maven repository manager during the image build.

b) A more efficient way with cache for maven dependencies downloaded

The approach is here the same but maven dependencies downloads that are cached in the docker builder cache.
The cache operation relies on buildkit (experimental api of docker).
To enable buildkit, the env variable DOCKER_BUILDKIT=1 has to be set (you can do that where you want : .bashrc, command line, docker daemon json file...).

Dockerfile :

# syntax=docker/dockerfile:experimental

########Maven build stage########
FROM maven:3.6-jdk-11 as maven_build
WORKDIR /app

#copy pom
COPY pom.xml .
    
#copy source
COPY src ./src

# build the app and download dependencies only when these are new (thanks to the cache)
RUN --mount=type=cache,target=/root/.m2  mvn clean package -Dmaven.test.skip

# split the built app into multiple layers to improve layer rebuild
RUN mkdir -p target/docker-packaging && cd target/docker-packaging && jar -xf ../my-app*.jar

########JRE run stage########
FROM openjdk:11.0-jre
WORKDIR /app

#copy built app layer by layer
ARG DOCKER_PACKAGING_DIR=/app/target/docker-packaging
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/lib /app/lib
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/BOOT-INF/classes /app/classes
COPY --from=maven_build ${DOCKER_PACKAGING_DIR}/META-INF /app/META-INF

#run the app
CMD java -cp .:classes:lib/* \
         -Djava.security.egd=file:/dev/./urandom \
         foo.bar.MySpringBootApplication

                                                                                                                                                                        
                                                                       
                                                                       
davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • I log on to stackoverflow just to comment and say thank you ! This should be the best answer ! – Aschay Apr 05 '21 at 13:07
  • @Shay Please to hear. That is the kind of comment that makes one to want to improve posts. – davidxxx Apr 05 '21 at 16:21
  • Awesome approaches! Thank you for this great answer. But I didnt get the point of copying layer by layer for spring app. Why not just make a fat jar and run it with java -jar command? – Deekshith Anand Dec 25 '21 at 19:23
  • Thanks. your answer, we recorded into out wiki as dev guide. Thanks for the contribution. – Sandeep Jan 29 '22 at 05:21
  • Hi, I keep getting the following error when I want to run the second stage (JRE run stage): `failed to load cache key: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed`. Any idea what's the problem here? – SkogensKonung Nov 19 '22 at 16:53
15

As a rule of thumb, you should build a fat JAR using Maven (a JAR that contains both your code and all dependencies).

Then you can write a Dockerfile that matches your requirements (if you can build a fat JAR you would only need a base os, like CentOS, and the JVM).

This is what I use for a Scala app (which is Java-based).

FROM centos:centos7

# Prerequisites.

RUN yum -y update
RUN yum -y install wget tar

# Oracle Java 7

WORKDIR /opt

RUN wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/7u71-b14/server-jre-7u71-linux-x64.tar.gz
RUN tar xzf server-jre-7u71-linux-x64.tar.gz
RUN rm -rf server-jre-7u71-linux-x64.tar.gz
RUN alternatives --install /usr/bin/java java /opt/jdk1.7.0_71/bin/java 1

# App

USER daemon

# This copies to local fat jar inside the image
ADD /local/path/to/packaged/app/appname.jar /app/appname.jar

# What to run when the container starts
ENTRYPOINT [ "java", "-jar", "/app/appname.jar" ]

# Ports used by the app
EXPOSE 5000

This creates a CentOS-based image with Java7. When started, it will execute your app jar.

The best way to deploy it is via the Docker Registry, it's like a Github for Docker images.

You can build an image like this:

# current dir must contain the Dockerfile
docker build -t username/projectname:tagname .

You can then push an image in this way:

docker push username/projectname # this pushes all tags

Once the image is on the Docker Registry, you can pull it from anywhere in the world and run it.

See Docker User Guide for more informations.

Something to keep in mind:

You could also pull your repository inside an image and build the jar as part of the container execution, but it's not a good approach, as the code could change and you might end up using a different version of the app without notice.

Building a fat jar removes this issue.

Matteo Pacini
  • 21,796
  • 7
  • 67
  • 74
  • HI,I used your example in my docker file to copy the fat jar in the image but the build fails for not being able to find the fat jar given the local path. Is it something like target/app.jar? – user_mda Jun 08 '15 at 16:01
  • Hi, is there a way i can download the artifact from nexus at runtime? To specify the artifact to be downloaded using properties and not an actual link to the jar itself? In the dockerfile: `RUN wget -O {project.build.finalname}.jar` But i want to download the above jar from nexus. – Pramod Setlur Apr 11 '16 at 18:24
  • 1
    Including a FAT JAR to code repo is slow for me. Is there any way to use maven to build the image? – WoLfPwNeR Apr 25 '16 at 17:31
  • 1
    Fat jars have some problems too, especially with signed jars. – Thorbjørn Ravn Andersen Nov 08 '17 at 10:32
  • 1
    As a rule of thumb never use a fat jar, packages that rely on the manifest or other data files within their jar's are likely to fail since there is no safe way to merge this data. Manifest files with matching paths inside a jar conflict and either first or last wins (can't remember which). The only time you should consider using a fat jar is if you have a very limited set of dependencies and you know very well that their jars do not have conflicting manifest data. Otherwise stay safe use jars as they have been designed to be used (i.e separately). – PiersyP Jan 19 '18 at 16:18
2

Jib as a Maven plugin, makes it easy and flexible enough to use Docker daemon or ignore it. Both in command line or in pom.xml.

For more info you can refer to build-a-docker-image-using-maven

Here is a simple pom.xml:

...
<properties>
    <java.version>11</java.version>
    <docker.name>amirkeshavarz/hellomavendocker</docker.name>
    <docker.REGISTRY_USERNAME>your-dockerhub-username</docker.REGISTRY_USERNAME>
    <docker.REGISTRY_PASSWORD>your-dockerhub-password</docker.REGISTRY_PASSWORD>
</properties>
...
<build>
    <plugins>
        ...
        <plugin>
            <groupId>com.google.cloud.tools</groupId>
            <artifactId>jib-maven-plugin</artifactId>
            <version>2.8.0</version>
            <configuration>
                <from>
                    <image>openjdk:17-jdk-alpine</image>
                    <auth>
                        <username>${docker.REGISTRY_USERNAME}</username>
                        <password>${docker.REGISTRY_PASSWORD}</password>
                    </auth>
                </from>
                <to>
                    <image>${docker.name}</image>
                    <auth>
                        <username>${docker.REGISTRY_USERNAME}</username>
                        <password>${docker.REGISTRY_PASSWORD}</password>
                    </auth>
                </to>
                <container>
                    <environment></environment>
                    <ports>
                        <port>8080</port>
                    </ports>
                    <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
                </container>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>build</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
...
Amir Keshavarz
  • 2,403
  • 3
  • 19
  • 19
0

Updated Docker file for @Mark O'Connor answer -

FROM maven:3.8.6-openjdk-18-slim AS build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package

FROM openjdk:20
COPY --from=build /home/app/target/simple-spring-application-0.0.1-SNAPSHOT.jar /usr/local/lib/my-app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/usr/local/lib/my-app.jar"]

build, run and logs (replace DOCKER-ID) -

$ docker build -t my-app .
$ docker run -dp 8080:8080 --rm -it my-app:latest
$ docker logs --follow <DOCKER-ID>

Link to git project - https://github.com/idanuda/simple-spring-application

Idan Yehuda
  • 524
  • 7
  • 21
-2
Create a Dockerfile
#
# Build stage
#

FROM maven:3.6.3-jdk-11-slim AS build

WORKDIR usr/src/app

COPY . ./

RUN mvn clean package

#
# Package stage
#

FROM openjdk:11-jre-slim

ARG JAR_NAME="project-name"

WORKDIR /usr/src/app

EXPOSE ${HTTP_PORT}

COPY --from=build /usr/src/app/target/${JAR_NAME}.jar ./app.jar

CMD ["java","-jar", "./app.jar"]
  • 2
    Hi, welcome to SO, would you mind adding some comments to your answer (e.g. a bit of description of what the code does)? Thank you – GBra 4.669 Jan 21 '21 at 17:36