How to Dockerize Spring Boot and MongoDB Project with Microservice Architecture?
A Spring Boot project will be Dockerized which uses Microservice Architecture and MongoDB.
We will use and mention Microservice Architecture, Layered Architecture, RESTful API Design, NoSQL Database, Docker, Docker-Compose, Swagger, and more.
- JDK (11)
- Maven (3.8.1)
- IDE (IntelliJ IDEA)
- MongoDB (5.0.3)
- Docker Desktop (20.10.11)
You can choose some different options.
Unfortunately, I cannot add the whole code. If you want to learn more about the project details you can check my GitHub.
Feel free to give stars if you enjoyed this article. I would appreciate it if you open an issue or contribute to the repository. It will always be better together!
What is Microservice Architecture?
Microservices are a distributed and loosely coupled version of monolithic architecture. It also has many benefits, but only when it is used in the right situations. Some of these benefits are independence, scalability, maintainability, and testability. Microservices should observe and apply the principles like single responsibility, loose coupling, and high cohesion.
What is NoSQL?
NoSQL is a high-performance, non-relational database with flexible data models. It is preferred when scalability, low latency, and high availability are needed. There are some types of NoSQL databases like Key-Value, Document (MongoDB), Graph, and Column-Oriented.
Creating a Spring Boot Application
Let’s see how to create our Microservice Architecture in Spring Boot. I will use just a microservice but if you want to learn how to use multiple microservices and communication between these, contact me.
We are moving forward with Spring Initializr and applying in the following picture. I’ve used Spring Boot 2.6.2 because it was a stable version at that time.
Now we can open the downloaded project in IDE. As you can see, dependencies were not added when creating the project because I want to add the required dependencies using Maven Dependency Management manually and create our package structure subsequently.
The module was added into the
microservices-project main project folder for using Microservice Architecture as you see below. We are going to use Layered Architecture in our microservice, let’s see how it was implemented.
Layered Architecture, is a well-established software application architecture that separates the responsibilities. It is divided into 3 main headings that try to explain our project.
- Presentation Layer: The purpose of the Presentation Layer is to display and collect information from the client.
APIpackage corresponds to Presentation Layer.
- Business Layer: The purpose of the Business Layer which is the heart of the project contains business codes, rules, and logic that are implemented here.
businesspackage corresponds to Business Layer.
- Persistence Layer: It transforms the business object into database domain models and contains Data Access Objects (DAO).
dataAccesspackages correspond to Persistence Layer.
- Data Layer: The purpose of the Data Layer is to perform CRUD (Create, Read, Update, Delete) operations in the database.
entitypackages correspond to the Data Layer.
In addition, we could have different Layered Architecture structures. What matters is the logical separation of codes.
@SpringBootApplication annotation includes
@ComponentScan which indicates a configuration class that declares one or more Bean methods.
@EnableMongoRepositories annotation required for using MongoDB repositories that indicates the Spring.
As you can see above, created Swagger which provides interface and documentation of API’s implementation methods and the main method of the project. In order to run the Application, you will use Product Microservice.
I have presented only one of the APIs which has been used in the application.
The Lombok package which configures entities has been used.
@Data annotation contains
@EqualsAndHashCode. So, we do not need to add these annotations manually because they have already been added.
@Document annotation is used to set the collection name. If the collection does not exist, it will be created. It is called the Code First approach.
@Id annotation indicates that the field is the Primary Key of the Collection. If you need to configure any field, you can use
@Repository annotation creates a bean for MongoRepository by Spring. Existing methods were used but we could also write our methods.
@Query annotation can also be used to specify custom queries.
@Service annotation indicates that the business logic are located here.
Dependency Injection is providing the instances that a manager class needs instead of constructing them itself. The classes that are applied will be more loosely coupled. I prefer to use the most popular alternative of Dependency Injection techniques, Constructor Injection in between 4–9 lines.
@RestController annotation includes
@ResponseBody and it handles every request that introduced for using RESTful web services.
@RequestMapping annotation is used for routing in controller classes.
As you can see, general application settings are identified under the Application Settings comment line. Database Settings and Other Settings are also identified under their comment lines. I would like to point out that other settings were added because of a bug that occurred between Spring and SpringFox.
The application is ready for running in the Product Application class. Our first API is available in Swagger or Localhost. If localhost is selected, HTTP Request should be sent correctly otherwise an error will have occurred (HTTP 405 Method Not Allowed).
The Spring Boot part has been completed. We can start the most important part of this project. I would like to explain Docker and the purpose of usage.
What is Docker?
Docker is the most popular open-source container technology. It provides; easy installation, running, testing, deploying, and maintaining of our applications. There are a lot of reasons for using Docker but the most significant reason is that the application could be used in every environment. If you want to learn Docker commands, click here. Let’s dive deeper.
Docker Image can be called a template with instructions for creating a Docker Container which is the packaged version of the application. We can create and publish our Docker Images or use other ones on the Docker Hub.
Docker Container is running or stopped version of the Docker Image and covers it. It is a structure in which we can manage runtime dependencies and provides process isolation with less resource consumption without using the virtualization of the operating system.
Dockerfile is a text document file used to specify a base image to Docker. The file name must be
Dockerfile and there is no extension. Every line in Dockerfile represents a layer.
Docker Compose is a .yml-based file that provides multiple containers that can be run and stopped with a single command. It consists of 4 main partitions which are
The application will be dockerized, then Docker Compose will be created. Docker Desktop must be started during these operations.
Just to dockerize using Dockerfile, we have to replace the 7th line of the
application.properties file with the text below. It cannot be localhost anymore because the application and the database will not be running on the same host.
The application must be built for dockerizing due to the row identified
/target/product-0.0.1-SNAPSHOT.jar in Dockerfile as seen in the following code snippet. Make sure that you are on the right path (
..\microservices-project) and run the following command. After that, you will see
BUILD SUCCESS the output and a jar file will be created under the
mvn clean install
Dockerfile must be created in the Product Module.
FROMcorresponds to the name of the base Docker Image. In this example
EXPOSEdetermines the port address where the container is running in Docker.
COPYcopies the specified files to the specified destination in the Docker Image.
CMDarranges the working order that executes the commands and parameters written in it.
..\microservices-project\product path and run the following command for dockerizing the application.
. the dot at the end shows that it will put the image which will be created in the same folder. Here we write whatever we want the tag name after
docker build -t product-service .
We can see the
product-service image in the Images tab of Docker Desktop.
After that, the following command should be running to set up port redirection at the host.
docker run -p 8000:8000 product-service
We can see the
product-service container in the Containers/Apps tab of Docker Desktop.
busy_mendel name has been assigned the container as the default name by Docker. Also if we want to assign a special name and run it in detached mode, the following command can be run. Detach mode means the container runs in the background and is it shown as
docker run --name=product-container -dp 8000:8000 product-service
You could make a request again from Swagger or anywhere, the application will be ready for that in the container.
If any change in the application, these processes must be repeated from the beginning. I am going to write a new article about CI/CD Pipeline to avoid this repetition.
Let’s stop the application in Docker Desktop before continuing.
versionDocker Compose version.
servicesinclude product-service and product-database.
buildmakes the Dockerfile run and extracts the image in
depends_onmakes the product-database written first run.
environmentcontains the variables of
application.propertiesfile because Docker does not see this file.
It is necessary to mention information for the communication between containers. The backend and the database containers have to communicate with same host. We did not define network and Docker will create default (bridge) network for these containers.
We must run the Dockerfile in the same path. The second file name is
docker-compose.yml, which is the Docker Compose file.
docker-compose -f docker-compose.yml up
As I said first, the
product-database is pulled from the specified
mongo image then the
product-service is pulled from the Dockerfile. Now the
product is running in Docker Compose!
Additional: Dockerizing without Dockerfile
Here I will just describe the easy Docker Image creation way. The application can be dockerized using the
spring-boot-maven-plugin without Dockerfile. We just need to make some additions in the part between the build tags of the
As you can see below, The part inside the
executions tags has been added. If you would like to compare the old and new versions, you can reach out here.
We will run the
mvn clean install code in the terminal. The process may take a long time than the normal build process. After this process is finished, the Docker Image is in Docker Desktop. As you know, the Docker Image can run as a Docker Container and add a Docker Compose file to this image.
In conclusion, we created the Spring Boot Project and use other new technologies in this article. If you like this article please do not forget to drop a comment and like. Thank you for your attention. I also want to say thanks to Bekir Can Baykal for his support.
While I am writing my articles, I assume that you know some basics. Nevertheless, if you have any questions which are related to these topics, please do not hesitate to contact me via Email or LinkedIn.
MongoDB: the application data platform
NEW Introducing native support for time series data - Get your ideas to market faster with an application data platform…