Development environment in Spring Boot with Docker

Lauri Hartikka
3 min readJan 9, 2016

--

One aspect of Docker is to provide the same environment throughout the different stages of software development process: e.g. in development, staging and production. But does it really make sense to run your application inside Docker when developing a Spring Boot application on your local computer. Here I go through some features common in Java development and how to make them work with Spring Boot and Docker: autoreload and debugging.

To achieve these properties I will be using the features found in the spring-dev-tools introduced in Spring Boot 1.3. Remember that the same techniques introduced here can also be applied if the containerized application is running on a remote server and without exposing any new ports.

The project used in these examples is found here

Autoreload

Spring-dev-tools introduces a hot restart feature which can also be applied to Spring Boot applications running inside a Docker container. Here are the steps how to utilize this feature.

  1. Add spring-boot-devtools as a dependency to your project. For instance in build.gradle:
dependencies {
compile("org.springframework.boot:spring-boot-devtools")
}

2. You will be connecting with a “autoreloader” to your running application. A shared secret must be provided for this to work. Add this your application.properties:

spring.devtools.remote.secret=thisismysecret

3. Build and start your containerized Spring Boot application. Here I will build the jar, add it to a Docker container and run the container.

Dockerfile:

FROM java:8WORKDIR /spring-tsers
ADD ./build/libs/spring-tsers.jar /spring-tsers/spring-tsers.jar
CMD java -jar spring-tsers.jar

Building and running the container in the host machine:

./gradlew build
docker build --tag=spring-tsers-dev .
docker run --publish=8080:8080 --rm=true --name=spring-tsers-dev spring-tsers-dev

4. Open the project in your IDE and connect to the running application with RemoteSpringApplication that is included in the spring-dev-tools package.

In Eclipse:
-Run Configurations -> Java Application -> New
-Choose org.springframework.boot.devtools.RemoteSpringApplication as the main class
-Choose spring-tsers as the project
-Set http://localhost:8080 to program arguments

The resulting configuration should look like this:

5. Make changes to the code in the IDE and save the files. Your container will be updated automatically!

(works also in IntelliJ IDEA. Just remember that IntelliJ IDEA does not automatically build the the project unlike Eclipse so you have to select e.g. Build -> Make Project for this to work)

Debugging

There are obviously many ways to get “inter-container” debugging to work, but I will use here the remote debug tunneling introduced in spring-dev-tools since it does not require forwarding any new ports in the docker container.

  1. Let’s first enable debugging in our containerized application by adding some parameters to the java command resulting a Dockefile like this:
FROM java:8
WORKDIR /spring-tsers
ADD ./build/libs/spring-tsers.jar /spring-tsers/spring-tsers.jar
CMD java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,suspend=n -jar spring-tsers.jar

And running the container (same commands as in autorelaod section)

./gradlew build
docker build --tag=spring-tsers-dev .
docker run --publish=8080:8080 --rm=true --name=spring-tsers-dev spring-tsers-dev

2. Start the RemoteSpringApplication as shown in the AutoReload Step 4.

3. Not only does the RemoteSpringApplication enable autoreloading, but it also opens a debug tunnel from the dockerized application to your local machine. The debug tunnel is by default opened to port 8000. So let’s attach a remote debugger to it:

In Eclipse:
-Debug configurations -> Remote Java Application -> New
-Choose spring-tsers as the Project
-Set connection properties to localhost and port 8000
Resulting a configuration like this:

4. Attach the remote rebugger. You can now debug your application running inside the Docker container.

Conclusions

IDEs play an important role in Java development. Getting the application “ouf of the IDE” to a dockerized container when developing and to still preserve the functionalities of the IDE results all kinds of problems, to which e.g. spring-dev-tools is addressing. I’m looking forward to what kind of new solutions spring-dev-tools (or any other such library) will provide in the future.

--

--