Dockerizing a Spring Boot Application

Sumitra Dhakre
Dev Genius
Published in
6 min readJun 14, 2022

--

Photo by Ian Taylor on Unsplash

Docker, an open-source project released in 2013, is a software platform for building applications based on containers. After its release docker quickly became popular because of the possibilities it opened up for software deployment and delivery. It's famous for its simplicity, fast scaling systems, flexible software delivery, and support for microservices architecture. It’s also at the heart of cloud computing.

During the development phase, it can help to ditch all the additional setups your application will need by just creating the needed containers. By dockerizing your application you can share your project with anyone and if they have docker installed it’s good to go. In this article, you’ll see how easily you can dockerize your spring boot app and debug it. So let’s get started.

Requirements

  • Any working spring boot application
  • Basic understanding of docker
  • Installed docker desktop
  • Intellij IDE
  • HeidiSQL for DB
  • Postman to test API

Project build

Open the spring boot application and build it. Here this project is an API, to query data from a MySQL DB. Any application will work for this article, as long as it’s producing an executable jar format. To build the project you can use either the UI maven menu

maven menu

Or you can use the mvn command

mvn clean install

After a successful build, if you look at the pom.xml during the build step with the spring-boot-maven-plugin it creates a jar file in the target folder. So we can just run it with the java jar command. Open a terminal and go to the target folder

target folder

cd target/

java -jar bookAPI-1.0-SANPSHOT.jar

To dockerize our application we’ll copy and run this jar inside a docker container. For the API to respond with data we’ll need the DB up and running so let's start by creating the mysql db service.

Docker compose

Since this is a multi-container application we’ll be using docker-compose. To create a compose file for this application we’ll need 2 services:

  • API
  • MySQL DB

Go to the root of your project and create a docker-compose.yml file.

DB Service

We start by defining the compose file version. A compose file consists of services, volumes, and networks. Here, I started by defining the db service.

docker-compose file with mysql db service
book-mysql: service nameimage: base image for creating the containercontainer_name: name of the containervolumes: to persists the sql, with format hostFileLocation:containerFileLocationports: to expose port mapping with format 
hostPort:containerPort
environment: to set env variables in this service's container, here password for the mysql dbhealthcheck: to test the container health by running a command at specified interval for timeout

Let's run and see the container in action

docker-compose up -d

db container creation

Here in the logs, we can see that the container has started correctly with the copied SQL. When no network is defined docker creates a default network for each container to join. You can connect to the DB container using the host mapped port and login as defined in the compose file.

HeidiSQL Session manager
mysql container with script data

It looks good with the data added along with the executed script. Now let's create the service for the API.

API Service

To run any jar application the service needs a JDK so I started by defining the JDK image. Then copy the jar from the target folder and run it with the java jar command just as we saw previously in the building part. Since the API won’t be much of use without a DB so I defined its dependency on the DB service.

compose file with api service
book-api: service nameimage: you can create your own base image by a Dockerfile to create image or use an existing one, like the openjdk11 image herecontainer_name: name of the containervolumes: to persists the jar inside the conatiner with format hostFileLocation:containerFileLocationcommand: to provide a default entrypoint by run the copied jar, accepts an array of stringsports: to expose port mapping with format 
hostPort:containerPort
depends_on: specifies service dependency on book-mysql service/container, will not start book-api if mysql fails

Now change the spring data source in the application.properties with the service name so spring will be able to find it.

spring-boot application.properties with DB service name

let’s build the project and open a terminal to test the containers.

docker-compose up -d

api container creation with default network

Thanks to the docker plugin in Intellij you can check the container logs in the service tab. From the container logs, we can see that the application has started correctly.

api container logs

Now open postman and test the response of our API to be sure everything works correctly.

allBook request in postman

To stop and remove all the containers use compose down command

docker-compose down

container removal

Debugging

Debugging is an important part of any application development. To debug our jar API first, we need to configure JVM to enable debugging. To do that use the following command in the docker-compose file and add the debug port mapping.

command: ["java","-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:debugPort","-Dspring.profiles.active=springProfile","-jar","bookapi.jar"]
ports:
- "8080:8080"
- "5252:5252"
docker-compose with debugging enabled

Now create a remote debug configuration in IntelliJ with the specified debug port.

IntelliJ remote debug configuration

By doing this you have two options to connect to the debugger. First by clicking on “Attach debugger” at the start of container logs

Or by clicking on the debug configuration of Intellij that we created earlier.

Let’s debug with a breakpoint by making a request from the postman.

breakpoint stop in IntelliJ

It works as expected. I hope this will help you to dockerize and debug your spring boot application. You can find this project here on Github.

Happy Dockerizing!!

--

--