Run SpringBoot application in Docker image

This is a short recipe on how to run your spring boot application within a docker image. The idea comes from John Thompson’s docker for java developer course, so be sure to check it out here https://www.udemy.com/docker-for-java-developers/.

What do we want to accomplish?

  • Create a fat (uber) jar of our application
  • Create a Docker file (a script telling docker how to build an image)
  • Build a docker image from a Dockerfile (no camel case! in Dockerfile)
  • Run a docker image, map the ports to the host

Lets get started… building the app and a Dockerfile

  1. Build your spring boot application. Run maven package or mvn package. Take the .jar from the target directory and put it where your Dockerfile will be.
  2. Create a Dockerfile and put in the following content:
FROM centos

RUN yum install -y java

VOLUME /tmp
ADD /spring-boot-web-0.0.1-SNAPSHOT.jar myapp.jar
RUN sh -c 'touch /myapp.jar'
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/myapp.jar"]

Explanation of a Dockerfile:

  • FROM centos: Pull the CENTOS image (kind of RedHat, but without support)
  • RUN yum install -y java: Install java, accept all questions as YES
  • VOLUME /tmp: Adding a temp volume, where spring boot will store temp files. Tomcat needs it to run properly, this is a default for spring boot
  • ADD /spring-boot-web-0.0.1-SNAPSHOT.jar myapp.jar: Add from current dir, the spring-boot-web-0….jar and rename it to myapp.jar
  • RUN sh -c ‘touch /myapp.jar’: Update the timestamp of the .jar file. Important for static resources, if cached, so new version is pulled down
  • ENTRYPOINT [“java”, “-Djava.security.egd=file:/dev/./urandom”, “-jar”, “/myapp.jar”]: ENTRYPOINT is a docker command, run java with param -Djava.security… this gives a random value and helps tomcat run faster. Run our myapp.jar.

Building the Docker image

Now we have a .jar and a Dockerfile. How do we build the docker image? From the command line, run the following command:

docker build -t spring-boot-docker .
  • -t: A tag name to tag the image
  • .: Look into current directory for a Dockerfile

Now the image should be built! You can check it out by running the docker images, which should list our newly created image, the spring-boot-docker.

Running the image

Its time to run our spring boot application from the newly created docker image. Let’s run it in detached mode and map the ports to our host machine.

docker run -d -p 8080:8080 spring-boot-docker

To check out that everything is up and running, you can go to the browser and try the http://localhost:8080. If something goes wrong, you can tail the logs from that specific container, check below my case.

docker logs 442c36457895 -f

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

2019-08-27 13:13:42.590  INFO 1 --- [           main] g.s.SpringBootWebApplication             : Starting SpringBootWebApplication v0.0.1-SNAPSHOT on 442c36457895 with PID 1 (/myapp.jar started by root in /)
2019-08-27 13:13:42.593  INFO 1 --- [           main] g.s.SpringBootWebApplication             : The following profiles are active: springdatajpa
2019-08-27 13:13:42.920  INFO 1 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@bebdb06: startup date [Tue Aug 27 13:13:42 UTC 2019]; root of context hierarchy
2019-08-27 13:13:44.883  INFO 1 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2019-08-27 13:13:44.902  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2019-08-27 13:13:44.907  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.14
2019-08-27 13:13:45.022  INFO 1 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-08-27 13:13:45.022  INFO 1 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2115 ms
2019-08-27 13:13:45.240  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2019-08-27 13:13:45.240  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2019-08-27 13:13:45.241  INFO 1 --- [ost-startStop-1] ...

That is it. Good luck!