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
- 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. - 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!