Spring Boot 3.1 was released on may 2023, among its many improvements, there is a new feature that simplifies the integration of Spring Boot application managing external services at development time using Docker Compose, with this, we can speed up the development process by automating the container management and creating the connection detail without any manual configuration of it.
To be in context, we are going to use Spring Boot 3.1 to develop our project, Docker Compose to define and run our Docker containers (In this example: PostreSQL and RabbitMQ).
Minimum requirements
Java 17
Spring-boot 3.1
Docker
Maven / Gradle
Setup
The project structure of the example
As you can see, there is a docker-compose.yml file in the root directory, now is necessary to set the dependency of Spring Boot Docker compose and set up the docker-compose.yml with the necessary containers:
docker-compose.yml
It is important to know that it’s allowed to use custom Docker containers for your application.
version: '3.8'
services:
db:
image:
postgres
container_name: 'postgresql-test'
restart: always
ports:
- "5432:5432"
environment:
POSTGRES_USERNAME: postgres
POSTGRES_PASSWORD: postgresPass
POSTGRES_DB: developers
#volumes:
- ./postgres-data:/var/lib/postgresql/data
# copy the sql script to create tables
- ./sql/create_tables.sql:/docker-entrypoint-initdb.d/create_tables.sql
rabbitmq:
image: rabbitmq:3-management-alpine
container_name: 'rabbitmq-test'
ports:
- 5672:5672
- 15672:15672
If you have a container defined in your docker-compose.yml and you don’t want to connect to your application, you can use this label to ignore it:
labels:
org.springframework.boot.ignore: true
Maven
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-docker-compose</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
Gradle
dependencies {
developmentOnly("org.springframework.boot:spring-boot-docker-compose")
}
Let the magic start!
The main advantage of using Spring Boot 3.1 is the possibility to detect Docker compose files and execute docker compose up
for you before connecting to the services, if the services are already running, it will use them and when you stop the application, automatically Spring Boot will execute docker compose stop
.
When we add this dependency, the Spring Boot application will do these steps:
- Search for a docker-compose.yml file and/or other common compose filenames in your application
- If we have a custom path for our docker compose file we can set it as we will see later on
- Execute docker compose up
- Create service connection beans for each container that we set
- Execute docker compose stop when the application is shutdown
In previous versions of Spring Boot we had to configure the connection details into our application properties file, now with spring-boot-docker-compose dependency and spring-boot 3.1 or higher, automatically detects the Docker images and connection details defined in docker-compose.yml and creates a ConnectionDetails bean for each service.
It is not necessary to keep the configuration details duplicated in application properties and Docker compose files!
Docker compose configuration
Here are some important configurations that you can use in application.properties file for spring-boot-docker-compose:
#Set a custom Docker compose file
spring.docker.compose.file=…./my-custom.yml
#Configure the lifecycle
#none - Do not start or stop Docker Compose
#start-only - Start Docker Compose when the application starts and leave it running
#start-and-stop - Start Docker Compose when the application starts and stop it when the JVM exits
spring.docker.compose.lifecycle-management=
#By default, Spring Boots Docker Compose support is disabled when running tests. To enable it, set
spring.docker.compose.skip.in-tests=false
#Disable spring-boot-docker-compose feature
spring.docker.compose.enabled=false
#Host or IP of the machine where the docker containers are started
spring.docker.compose.host=
#Set the timeout to stop
spring.docker.compose.stop.timeout=1m
How to activate Docker compose Profiles
Docker compose profiles could be used as Spring profiles, they can let you adjust different Docker compose configurations for different environments, providing greater flexibility for adapting to deployment scenarios. To activate a new profile we can set this property:
spring.docker.compose.profiles.active=myprofile
Run the application
Now, let’s run the Spring Boot application and see the magic:
In this example, we are going to use Maven using mvn spring-boot:run
to run the application, for Gradle use ./gradlew bootRun:
After running our application, Spring Boot will detect the Docker compose file and the Docker containers (Output log).
--- [ restartedMain] c.e.d.DockerComposeDemoApplication : Starting DockerComposeDemoApplication using Java 17.0.9 with PID 4570 (/mnt/c/IdeaProjects/Personal_Projects/dockerComposeDemo/dockerComposeDemo/target/classes started by lot in /mnt/c/IdeaProjects/Personal_Projects/dockerComposeDemo/dockerComposeDemo)
--- [ restartedMain] c.e.d.DockerComposeDemoApplication : No active profile set, falling back to 1 default profile: "default"
--- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
--- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
--- [ restartedMain] .s.b.d.c.l.DockerComposeLifecycleManager : Using Docker Compose file '/mnt/c/IdeaProjects/Personal_Projects/dockerComposeDemo/dockerComposeDemo/docker-compose.yml'
--- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container postgresql-test Created
--- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container rabbitmq-test Created
--- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container postgresql-test Starting
--- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container rabbitmq-test Starting
--- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container rabbitmq-test Started
--- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container postgresql-test Started
--- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container rabbitmq-test Waiting
--- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container postgresql-test Waiting
--- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container rabbitmq-test Healthy
--- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container postgresql-test Healthy
--- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
--- [ restartedMain] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 235 ms. Found 2 JPA repository interfaces.
--- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
And now we have the Spring Boot application running and connected to Docker containers!
Conclusion
With this new feature we can set our containers configuration in docker-compose.yml and just run our application.
New database for your project? No problem, just add it in your Docker compose file and start working. It is not necessary to set the configuration in the property file, read “readme” documents or obsolete wikis explaining how to set up your environment to start working and waste time in all this process, just flow with Spring Boot and automatize!