← Back to list

Building a Production-Ready Stack: Spring Boot 3, JDK 17, and Percona MongoDB 8

Part 1: Kickstart your journey into scalable data layers with containerized infrastructure and Spring Boot 3.

Owen Bringino · 2026-01-31 18:19 · 0 claps · 2.7 min read
#spring-boot #mongodb #docker #java #percona
Open on Medium ↗
Wiki topics: ☁️ · DevOps & Cloud

Building a Production-Ready Stack: Spring Boot 3, JDK 17, and Percona MongoDB 8

Part 1: Kickstart your journey into scalable data layers with containerized infrastructure and Spring Boot 3.

Welcome to the first installment of my new MongoDB + Spring Boot Tutorial Series! In this series, we’re going to move past simple “Hello World” examples and focus on building robust, enterprise-grade data layers.

Today, we’re kicking things off by setting up a modern development environment using Percona Server for MongoDB 8, Spring Boot 3.2, and Swagger for interactive API documentation

Full Source Code: You can follow along with the complete project here: https://github.com/owenrb/mongo-spring-01

Why Percona MongoDB?

While standard MongoDB is great, Percona Server for MongoDB brings enterprise-grade features to the open-source community — including advanced security, a pluggable storage engine, and enhanced monitoring capabilities. If you are planning for scale and performance, starting with Percona is a smart move.

1. The Foundation: Docker Compose

Our infrastructure is managed via Docker. This configuration spins up Percona MongoDB 8 and Mongo-Express for a web-based GUI.

services:
  mongodb:
    image: percona/percona-server-mongodb:8.0
    container_name: mongodb_percona
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=secretpassword
    volumes:
      - mongodb_data:/data/db
    ports:
      - "27017:27017"
    restart: always

  mongo-express:
    image: mongo-express
    container_name: mongo_express
    depends_on:
      - mongodb
    environment:
      - ME_CONFIG_MONGODB_ADMINUSERNAME=admin
      - ME_CONFIG_MONGODB_ADMINPASSWORD=secretpassword
      - ME_CONFIG_MONGODB_URL=mongodb://admin:secretpassword@mongodb:27017/
      - ME_CONFIG_BASICAUTH_USERNAME=webuser
      - ME_CONFIG_BASICAUTH_PASSWORD=webpassword
    ports:
      - "8081:8081"
    restart: always

volumes:
  mongodb_data:

2. Launching the Infrastructure

To start the database and the UI, navigate to the directory containing your docker-compose.yml file and run the following command in your terminal:

docker compose up -d

Verifying the Setup: You can confirm your containers are running by typing docker ps. You should see mongodb_percona and mongo_express with a status of "Up".

Setting Up the Project: The pom.xml

A clean pom.xml is the backbone of a Spring Boot application. For this project, we are using Spring Boot 3.2.2 and Java 17. The key is to manage the interaction between the Maven Compiler and Lombok's annotation processor to avoid compilation errors.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.36</version>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
        <version>2.3.0</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>1.18.36</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

The Backend: Clean, Reactive, and Modern

With JDK 17 and Spring Boot 3.2, we build a data layer that is powerful yet concise.

1. The Model & Repository

Lombok’s @Data handles the boilerplate, while MongoRepository provides full CRUD functionality for free.

@Document(collection = "tasks")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Task {
    @Id
    private String id;
    private String description;
    private boolean completed;
}

public interface TaskRepository extends MongoRepository<Task, String> {}

2. The REST Controller

Using @RequiredArgsConstructor handles constructor injection—the recommended way to manage dependencies in Spring.

@RestController
@RequestMapping("/api/tasks")
@RequiredArgsConstructor
@Tag(name = "Task Management", description = "Endpoints for Task CRUD")
public class TaskController {

    private final TaskRepository repository;

    @GetMapping
    @Operation(summary = "List all tasks")
    public List<Task> getAll() { return repository.findAll(); }

    @PostMapping
    @Operation(summary = "Create a new task")
    public Task create(@RequestBody Task task) { return repository.save(task); }

    @PutMapping("/{id}")
    public Task update(@PathVariable String id, @RequestBody Task details) {
        return repository.findById(id).map(task -> {
            task.setDescription(details.getDescription());
            task.setCompleted(details.isCompleted());
            return repository.save(task);
        }).orElseThrow(() -> new RuntimeException("Task not found"));
    }

    @DeleteMapping("/{id}")
    public void delete(@PathVariable String id) { repository.deleteById(id); }
}

Running and Verifying the App

To launch your stack, run the following in your terminal:

mvn clean spring-boot:run

What to Look for in the Logs

  • Server Start: Confirm Tomcat started on port 8080.
  • Database Connection: Watch for org.mongodb.driver.cluster logs confirming a connection to localhost:27017.

Interactive Documentation

Navigate to: [http://localhost:8080/swagger-ui/index.html](http://localhost:8080/swagger-ui/index.html)

Here, you can use the “Try it out” feature to test your endpoints. You can also verify data changes in Mongo-Express at [http://localhost:8081.](http://localhost:8081.)

What’s Next?

Now that we have a functional single-node setup, we need to talk about High Availability. In the next part of this series, we will dive into Advanced Topics: MongoDB Replica Sets and see how Spring Boot handles automatic failover.

Stay tuned, and happy coding!


메타데이터
post_id
efd22f597bbf
slug
building-a-production-ready-stack-spring-boot-3-jdk-17-and-percona-mongodb-8-efd22f597bbf
url
https://medium.com/@owenrbee/building-a-production-ready-stack-spring-boot-3-jdk-17-and-percona-mongodb-8-efd22f597bbf
canonical_url
https://medium.com/@owenrbee/building-a-production-ready-stack-spring-boot-3-jdk-17-and-percona-mongodb-8-efd22f597bbf
author_url
https://medium.com/@owenrbee
status
ok
fetched_at
2026-07-13 06:23:13