With the release of Spring Boot 3.1, the Spring team introduced a neat support to start all required containers for your application by a single Docker-Compose script that can be checked in with your application.
Docker-Compose is a technology that can start multiple Docker containers with a given set of parameters by one single command and a configuration file. Starting a Docker container by the command line is sometimes quite a complex task, depending on how many start parameters, configuration files and port mappings the container needs. This can all be specified in a Docker-Compose file, that includes all necessary start parameters in one file for all required containers. With Spring 3.1, this file can now be included in the code base of your application and is even executed when the application starts.
To include Docker-Compose support in your app, pick the new Spring Boot starter from the Spring Initializr:

This will add the compose dependency into your Maven or Gradle build file:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-docker-compose</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>If you have other Spring Boot starters for the integration of databases in you app, you will also get an example Docker-Compose file (compose.yml) to start these dependencies. For an example compose file, I used the Spring Boot starter for MongoDB, RabbitMQ and Redis, and ended up with a neat default compose file to start all three containers with a set up default parameters:
services:
mongodb:
image: 'mongo:latest'
environment:
- 'MONGO_INITDB_DATABASE=mydatabase'
- 'MONGO_INITDB_ROOT_PASSWORD=secret'
- 'MONGO_INITDB_ROOT_USERNAME=root'
ports:
- '27017'
rabbitmq:
image: 'rabbitmq:latest'
environment:
- 'RABBITMQ_DEFAULT_PASS=secret'
- 'RABBITMQ_DEFAULT_USER=myuser'
ports:
- '5672'
redis:
image: 'redis:latest'
ports:
- '6379'
Docker-Compose MongoDB Example
Next, let’s look how we can use the MongoDB container in a simple example application.
To access data from a MongoDB we first need a repository that offers the basic CRUD operations. With the spring-boot-starter-data-mongodb dependency in the application, you can create the repository by this simple interface:
import org.springframework.data.mongodb.repository.MongoRepository;
public interface BookRepository extends MongoRepository<Book, Integer> {
}The interface uses the Book record that I will to store the example data:
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
public record Book(@Id Integer id, String name, String author) {
}With these two classes and the default compose.yml file in the root of the project, we are ready to start the application.
In the logs we can see the container being started:

If you want to have persistent data storage between two application runs, you can mount an external folder into the docker container to save your data. This is done by adding a volume to the default compose.yml (line 9-10):
services:
mongodb:
image: 'mongo:latest'
container_name : 'jot_mongo'
environment:
- 'MONGO_INITDB_DATABASE=jot_db'
- 'MONGO_INITDB_ROOT_PASSWORD=secret'
- 'MONGO_INITDB_ROOT_USERNAME=root'
volumes:
- './mongo-volume:/data/db'
ports:
- '27017'This configuration will create the folder mongo-volume in your projects root directory, which will contain the MongoDB database files.

Finally, let’s write a Unit-test to test the simple CRUD operations of our repository.
To use the compose file in a Unit-Test, we need to activate the compose support for tests in the application.properties file. By default, this is deactivated for tests:
spring.docker.compose.skip.in-tests=falseWith this configured, we can write a simple test of the CRUD functions:
package com.jot;
import java.util.Optional;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class BookRepositoryTest {
@Autowired
private BookRepository bookRepo;
@BeforeEach
public void clean() {
bookRepo.deleteAll();
}
@Test
void testInsertDeleteGet() {
bookRepo.insert(new Book(1, "Lord Of the Rings", "J.R.R. Tolkien"));
Book result = bookRepo.findById(1).get();
Assertions.assertEquals("Lord Of the Rings", result.name());
bookRepo.deleteById(1);
Optional<Book> result2 = bookRepo.findById(1);
Assertions.assertNull(result2.orElse(null));
}
}
Running this test will start the MongoDB container in the background and execute the test:

I hope this simple example shows how easy it is to start your local containers with some minimal configuration locally. This new mechanism is so easy that there is almost no reason to not use it for your local development.
If you want to check out the code, you can find it here on GitHub. As always, if you liked this post, please star the repository or leave a comment.
Schreibe einen Kommentar