In this blog post we will see how we can use docker containers during development time using docker compose files in Spring Boot 3.1 which simplifies the development and testing efforts by providing infrastructure.
In Spring Boot 3.1, framework has support for containers during development time either using docker-compose file or Testcontainers.
In this blog post we will see the dev containers support with docker compose module in Spring Boot application.
If you are using docker compose file to provision infrastructure like database or Message queue with earlier spring boot version, you had to manually start the services from docker compose file before starting your application and stopping once application is tested with following command.
Starting docker compose services
docker-compose upCode language: Java (java)
Stopping the servicess
docker-compose downCode language: Java (java)
Docker Compose Support
Starting with version 3.1, Spring Boot framework comes with new module called, “spring-boot-docker-compose” . It provides integration with Docker Compose file
If you want to use the docker compose module, add the following dependency in your pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-docker-compose</artifactId> </dependency>Code language: Java (java)
and place docker compose file in project root folder.
docker-composeCLI application needs to be on your path in order for Spring Boot’s support to work correctly.
docker compose file could be named as one of the following.
spring -docker-compose module adds the support to start and stop services from docker compose when spring boot application starts and stops automatically.
When docker compose modules is included as a dependency Spring Boot will do the following:
- Search for a
compose.ymland other common compose filenames in your application directory
docker compose upwith the discovered
- Create service connection beans for each supported container
docker compose downwhen the application is shutdown
If you are starting database with compose file
In below startup logs , you can see that, spring boot docker module recognized the presence of compose file and started service defined in it.
INFO 20780 --- [ main] .s.b.d.c.l.DockerComposeLifecycleManager : Found docker compose file 'D:\IdeaProjects\springboot3-dev-containers\docker-compose.yml' INFO 20780 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Network springboot3-dev-containers_default Creating INFO 20780 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Network springboot3-dev-containers_default Created INFO 20780 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container springboot3-dev-containers-postgres-1 Creating INFO 20780 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container springboot3-dev-containers-postgres-1 Created INFO 20780 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container springboot3-dev-containers-postgres-1 Starting INFO 20780 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container springboot3-dev-containers-postgres-1 Started INFO 20780 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container springboot3-dev-containers-postgres-1 Waiting INFO 20780 --- [utReader-stderr] o.s.boot.docker.compose.core.DockerCli : Container springboot3-dev-containers-postgres-1 HealthyCode language: Java (java)
Service Connections is new mechanism introduced in Spring Boot 3.1
A service connection is a connection to any remote service such as database, Message Queue, Elastic Search or Cache Service.
Spring Boot’s auto-configuration can read the details of a service connection and use them to establish a connection to a remote service.
If you start a database service using docker compose file, service connection can read username,password and url of the database and use those details to connect to database from spring boot project. i.e No need to define those properties in the application.properties file
Spring Boot gives higher preference to service connection details than any connection-related configuration properties.
i.e. If Database connection details are configured in application.properties, and if you are using docker-compose module then environment variables (which form connection information) defined in docker compose file take precedence.
ServiceConnection feature is supported by limited no of services at the moment.
Service connections are established by using the image name of the container. The following service connections are currently supported:
|Connection Details||Matched on|
|Containers named “cassandra”|
|Containers named “elasticsearch”|
|Containers named “gvenzl/oracle-xe”, “mariadb”, “mssql/server”, “mysql”, or “postgres”|
|Containers named “mongo”|
|Containers named “gvenzl/oracle-xe”, “mariadb”, “mssql/server”, “mysql”, or “postgres”|
|Containers named “rabbitmq”|
|Containers named “redis”|
|Containers named “openzipkin/zipkin”.|
Using Custom Images
Sometimes you may need to use your own version of an image to provide a service. Any custom image can be used as long as it performs the same as the standard image. Any environment variables supported by the standard image must be used in your custom image as well.
If your image uses a different name, you can add a label in your docker compose file to allow Spring Boot to provide a service connection. Use a label named org.springframework.boot.service-connection to provide the service name.
services: postgres: image: 'mydatabase/mypostgres:13.2' ports: - '5432' labels: org.springframework.boot.service-connection: postgresCode language: Java (java)
Skipping Specific Containers
If you have a container image defined in your docker compose file that you don’t want connected to your application you can ignore it using label. Spring Boot will ignore any container labelled with org.springframework.boot.ignore.
This feature very useful when you have more than service defined in your docker compose but you want to run selected service during application run, then label all unwanted services with ignore.
services: redis: image: 'postgres:13.2' ports: - 5432:5432 labels: org.springframework.boot.ignore: trueCode language: Java (java)
Using a Specific Compose File
If your docker compose file not in the root of the project or its named differently than default recognized file names, you can use spring.docker.compose.file in your
application.yaml to point to a different file. Properties can be defined as an exact path or a path that’s relative to your application.
spring.docker.compose.file=./local-dev/docker-compose.ymlCode language: Java (java)
Waiting for Container Readiness
Containers started by Docker Compose may take some time to become fully ready. The recommended way of determining readiness is to add a healthcheck section in your docker compose file under the service definition.
Because it is common for healthcheck configuration to be omitted from compose.yml files, Spring Boot also checks for service readiness directly. A container is deemed ready by default when a TCP/IP connection to its mapped port can be established.
You may deactivate it per container by adding an org.springframework.boot.readiness-check.tcp.disable label to your compose.yml file.
services: redis: image: 'postgres:13.2' ports: - '5432' labels: org.springframework.boot.readiness-check.tcp.disable: trueCode language: Java (java)
You can also define timeout values in your
spring.docker.compose.readiness.tcp.connect-timeout=10s spring.docker.compose.readiness.tcp.read-timeout=5sCode language: Java (java)
Controlling the Docker Compose Lifecycle
By default Spring Boot calls
docker compose up when your application starts and
docker compose down when it’s shutdown. If you prefer to have different lifecycle management you can use the
The following values are supported:
- none – Do not start or stop Docker Compose
- start-only – Start Docker Compose on application startup and leave it running
- start-and-stop – Start Docker Compose on application startup and stop it on application shutdown
In addition you can use the spring.docker.compose.startup.command property to change if
docker up or
docker start is used. The spring.docker.compose.shutdown.command allows you to configure if
docker down or
docker stop is used.
The following example shows how lifecycle management can be configured:
spring.docker.compose.lifecycle-management=start-and-stop spring.docker.compose.startup.command=start spring.docker.compose.shutdown.command=stop spring.docker.compose.shutdown.timeout=1mCode language: Java (java)
Using Docker Compose Profiles
Docker Compose profiles are similar to Spring profiles in that they let you adjust your Docker Compose configuration for specific environments. If you want to activate a specific Docker Compose profile you can use the spring.docker.compose.profiles.active property in your
spring.docker.compose.profiles.active=devCode language: Java (java)
You can download the source code this blog post from GitHub