Developing Spring Boot Applications in Docker locally

Vibhor Mahajan
Trantor
Published in
5 min readSep 29, 2021

--

with a focus on giving a great developer experience and productivity

Photo by Ian Taylor on Unsplash

Docker provides an unprecedented way of creating portable dev environments which are quick to set up and easy to extend. Creating containerized applications has the promise of the lowest dev/prod parity. However, any developer would take the path of least resistance when it comes to day-to-day coding workflows. The instructions provided for containerizing the spring boot applications often lack the focus on doing so on the local dev box. These also are not tested on all the three commonly used operating systems — Windows, OSX, and Linux. This tutorial aims to bridge the gap.

Step 1: Download and install Docker

Unless you already have Docker installed, you can download and install it from https://docs.docker.com/get-docker/

Step 2: Create a Spring Boot Application

You can use the web-based Spring Initializr or a different method to create a spring boot application.

A screenshot from Spring Initalizr

I have added three dependencies for the purpose of this tutorial:

  • [Required] Spring Boot DevTools — Provides fast application restarts, LiveReload, and configurations for enhanced development experience.
  • [Optional] Spring Reactive Web — Build reactive web applications with Spring WebFlux and Netty.
  • [Optional] Lombok — Java annotation library which helps to reduce boilerplate code.

Here are the maven dependencies:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

Step 3: Develop code inside Docker

Following are some capabilities that we wish to have:

  1. Being able to develop code available in your local file system using an IDE such as IntelliJ Idea, VSCode or Eclipse (or STS)
  2. Avoid having to compile on the host
  3. Being able to automatically build and deploy changes to without having to manually build or restart the application

The first step is to create a Dockerfile at the application root.

Eclipse Temurin is the base image having the Open JDK 11 installed on a Debian OS.

The utility called “inotify-tools” helps monitor changes in the code.

We use “dos2unix” to workaround to normalize the line endings in files created in Windows and make them able to run inside the unix-based container.

Create a run.sh file to help automate the tasks to be run at application boot-up

The local source code directory is mounted inside the container at the path /app

A container’s local storage is supposed to be volatile. We would hate to lose our maven dependencies which can take a few minutes to cache the first time when we run the application. So, we have mounted the .m2 directory from inside the container to be available as a local directory on our local file system. This will allow you to destroy the container and recreate it without hassle.

The following ports are exposed:

  1. The application runs on port 8080.
  2. Port 35729 allows the livereload plugin to listen to changes
  3. Port 5005 makes the debugger available to the IDE

The docker image can be built using the command

docker-compose build

and the container can be run using the following

docker-compose up

Step 4: Debugging with your IDE

I’ll use IntelliJ Idea for the demonstration. Search for “remote debugging” in the context of your favorite IDE to find the instructions for your workflow.

Edit the run configurations

Add new configuration

Choose “Remove JVM Debug”. The default options should work. Here’s what my configuration looks like:

Now select your new remote configuration from the dropdown and hit the debug button

Here’s what a successful console output looks like

Now add a breakpoint and run your API. It should hit your breakpoint.

Make some changes to the codebase and observe that the code rebuilds automatically.

Resources

The source code for this tutorial can be found on https://github.com/v1bh0r/spring-boot-local-dev-docker/

Troubleshooting

Most of the issues that I have encountered with the setup have been around volume mounts on Windows.

You might face issues such as permission errors on the mounted source code or the code changes not triggering a re-build automatically.

Being aware of if you are using Hypervisor or WSL1 or WSL2 is the key to solving these issues.

Vibhor Mahajan is the VP — Software Product Development and Innovation at Trantor. His job at Trantor is to establish trust with new challenging accounts, develop novel practices, and scale software engineering teams. He provides consulting and thought leadership to help establish consistent and sustainable software engineering delivery.

https://www.linkedin.com/in/vibhormahajan

--

--

Vibhor Mahajan
Trantor

A Software Craftsman, he loves building Software Products, and high performance Software Engineering Teams http://bit.ly/2YaU6zY