In this tutorial, you will learn how to create two Spring Boot microservices and deploy them using Docker Compose, a tool designed for defining and running multi-container Docker applications. This beginner-friendly guide covers everything from project setup to containerization and inter-service communication.
What You’ll Learn
- Creating two microservices:
employee-service
anddepartment-service
. - Containerizing Spring Boot applications with Docker.
- Using Docker Compose to manage multi-container applications.
Introduction to Microservices and Docker Compose
Microservices architecture enables the development of small, independent services that communicate with each other via APIs. Each microservice handles a distinct piece of functionality and can be scaled or updated independently. Docker Compose simplifies the orchestration of multi-container applications, making it easier to define and run services simultaneously in isolated environments.
Why Docker Compose?
- Simplified deployment: Easily define multi-container applications in a single YAML file.
- Networking: Automatically connects services to a network.
- Scalability: Scale individual services as needed.
Prerequisites
Make sure you have the following tools installed before getting started:
- JDK 17 or later
- Maven or Gradle
- Docker and Docker Compose
- IDE (IntelliJ IDEA, Eclipse, etc.)
Step 1: Create the Projects
We'll create two Spring Boot microservices:
- employee-service: Manages employee details.
- department-service: Fetches employee data from
employee-service
.
Step 2: Set Up employee-service
2.1 Create the Project
Go to Spring Initializr and generate a new Spring Boot project with the following dependencies:
- Spring Web
- Spring Boot Actuator
2.2 Configure application.properties
In the src/main/resources/application.properties
file, configure the application properties for employee-service
:
server.port=8081
spring.application.name=employee-service
Explanation:
- server.port=8081: Specifies the port for
employee-service
. - spring.application.name=employee-service: Defines the application name.
2.3 Create an Employee Model
Create an Employee
class to represent employee data.
package com.example.employeeservice;
public class Employee {
private String id;
private String name;
private String department;
// Constructor, getters, and setters
public Employee(String id, String name, String department) {
this.id = id;
this.name = name;
this.department = department;
}
}
2.4 Create a Controller
Create a REST controller to handle employee-related requests.
package com.example.employeeservice;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EmployeeController {
@GetMapping("/employees/{id}")
public Employee getEmployee(@PathVariable String id) {
return new Employee(id, "John Doe", "Engineering");
}
}
2.5 Create a Dockerfile
Create a Dockerfile
in the root of the employee-service
project:
FROM openjdk:17-jdk-alpine
WORKDIR /app
COPY target/employee-service-0.0.1-SNAPSHOT.jar employee-service.jar
EXPOSE 8081
ENTRYPOINT ["java", "-jar", "employee-service.jar"]
Step 3: Set Up department-service
3.1 Create the Project
Create another Spring Boot project using Spring Initializr with the following dependencies:
- Spring Web
- Spring Boot Actuator
- OpenFeign (for communication between services)
3.2 Configure application.properties
Configure the department-service
in the application.properties
file:
server.port=8082
spring.application.name=department-service
employee.service.url=http://employee-service:8081
Explanation:
- employee.service.url: Defines the URL for
employee-service
for communication.
3.3 Enable Feign Clients
Add the @EnableFeignClients
annotation to the main application class:
package com.example.departmentservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class DepartmentServiceApplication {
public static void main(String[] args) {
SpringApplication.run(DepartmentServiceApplication.class, args);
}
}
3.4 Create Feign Client Interface
Create a Feign client to communicate with employee-service
:
package com.example.departmentservice;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name = "employee-service", url = "${employee.service.url}")
public interface EmployeeServiceClient {
@GetMapping("/employees/{id}")
Employee getEmployeeById(@PathVariable String id);
}
3.5 Create a Controller
Create a REST controller to fetch employee data through the Feign client:
package com.example.departmentservice;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DepartmentController {
private final EmployeeServiceClient employeeServiceClient;
public DepartmentController(EmployeeServiceClient employeeServiceClient) {
this.employeeServiceClient = employeeServiceClient;
}
@GetMapping("/departments/{employeeId}")
public String getEmployeeDepartment(@PathVariable String employeeId) {
Employee employee = employeeServiceClient.getEmployeeById(employeeId);
return "Employee " + employee.getName() + " works in the " + employee.getDepartment() + " department.";
}
}
3.6 Create a Dockerfile
Create a Dockerfile
for department-service
:
FROM openjdk:17-jdk-alpine
WORKDIR /app
COPY target/department-service-0.0.1-SNAPSHOT.jar department-service.jar
EXPOSE 8082
ENTRYPOINT ["java", "-jar", "department-service.jar"]
Step 4: Build Docker Images
Navigate to the root directories of each service and run the following commands to build Docker images:
For employee-service
:
mvn clean package
docker build -t employee-service .
For department-service
:
mvn clean package
docker build -t department-service .
Step 5: Create Docker Compose File
Create a docker-compose.yml
file in the root directory to define the multi-container setup:
version: '3.8'
services:
employee-service:
image: employee-service
build:
context: ./employee-service
ports:
- "8081:8081"
networks:
- microservices-net
department-service:
image: department-service
build:
context: ./department-service
ports:
- "8082:8082"
networks:
- microservices-net
networks:
microservices-net:
driver: bridge
Explanation:
- services: Defines both
employee-service
anddepartment-service
. - networks: Creates a bridge network for service communication.
Step 6: Run Docker Compose
Navigate to the directory with the docker-compose.yml
file and run:
docker-compose up --build
Docker Compose will build the images and start the containers.
Step 7: Test Microservices Communication
Use Postman or a browser to test the endpoints:
- employee-service: http://localhost:8081/employees/1
- department-service: http://localhost:8082/departments/1
The response from department-service
should include employee details fetched from employee-service
.
Conclusion
You’ve successfully set up two Spring Boot microservices, containerized them using Docker, and deployed them with Docker Compose. This structure is scalable and allows for independent updates to each service, making it easier to maintain a microservices architecture.
Next Steps:
- Add databases (e.g., MySQL) to the services.
- Implement service discovery using Spring Cloud.
Comments
Post a Comment