In this tutorial, we will:
- Create two microservices using Spring Boot:
employee-service
anddepartment-service
. - Containerize both services using Docker.
- Use Docker Compose to orchestrate the deployment of these microservices.
What You'll Learn:
- How to use Docker Compose to define and run multi-container Docker applications.
- How to set up communication between multiple Spring Boot microservices.
Introduction to Docker Compose
Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application's services, networks, and volumes. Then, with a single command, you can create and start all the services from your configuration.
Prerequisites
Before starting, ensure you have the following:
- JDK 17 or later
- Maven or Gradle
- Docker and Docker Compose
- IDE (like IntelliJ IDEA or Eclipse)
Step 1: Create Two Spring Boot Projects
We will create two Spring Boot microservices:
- employee-service: Manages employee data.
- department-service: Manages department data and fetches employee details from the
employee-service
.
Step 2: Set Up employee-service
2.1 Create the Project
Go to Spring Initializr and create a new Spring Boot project with the following dependencies:
- Spring Web
- Spring Boot Actuator
2.2 Configure application.properties
Set up your application.properties
for employee-service
:
server.port=8081
spring.application.name=employee-service
2.3 Create the Employee Model
Define an Employee
model:
package com.example.employeeservice;
public class Employee {
private String id;
private String name;
private String department;
public Employee(String id, String name, String department) {
this.id = id;
this.name = name;
this.department = department;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getDepartment() {
return department;
}
}
2.4 Create a Controller
Create a REST controller to expose employee-related endpoints:
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 Dockerfile for employee-service
In the root directory of the project, create a Dockerfile
:
# Use an official JDK runtime as a parent image
FROM openjdk:17-jdk-alpine
# Set the working directory in the container
WORKDIR /app
# Copy the JAR file into the container
COPY target/employee-service-0.0.1-SNAPSHOT.jar employee-service.jar
# Expose port 8081
EXPOSE 8081
# Run the application
ENTRYPOINT ["java", "-jar", "employee-service.jar"]
Step 3: Set Up department-service
3.1 Create the Project
Go to Spring Initializr and create a new Spring Boot project with the following dependencies:
- Spring Web
- Spring Boot Actuator
- OpenFeign (for inter-service communication)
3.2 Configure application.properties
Configure your application.properties
for department-service
:
server.port=8082
spring.application.name=department-service
# URL of employee-service
employee.service.url=http://employee-service:8081
3.3 Enable Feign Client
Add the @EnableFeignClients
annotation in 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
Define a Feign client to communicate with the 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 the Employee Model
Create an Employee
class in department-service
:
package com.example.departmentservice;
public class Employee {
private String id;
private String name;
private String department;
// Constructor, getters, and setters
public Employee() {}
public Employee(String id, String name, String department) {
this.id = id;
this.name = name;
this.department = department;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getDepartment() {
return department;
}
}
3.6 Create a Controller
Create a REST controller in department-service
to handle department-related requests and fetch employee details:
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.7 Create Dockerfile for department-service
In the root directory of the project, create a Dockerfile
:
# Use an official JDK runtime as a parent image
FROM openjdk:17-jdk-alpine
# Set the working directory in the container
WORKDIR /app
# Copy the JAR file into the container
COPY target/department-service-0.0.1-SNAPSHOT.jar department-service.jar
# Expose port 8082
EXPOSE 8082
# Run the application
ENTRYPOINT ["java", "-jar", "department-service.jar"]
Step 4: Create Docker Compose File
In the root directory of your project, create a docker-compose.yml
file. This file will define both employee-service
and department-service
, as well as the network for communication between them.
version: '3'
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"
environment:
- EMPLOYEE_SERVICE_URL=http://employee-service:8081
networks:
- microservices-net
networks:
microservices-net:
driver: bridge
Explanation:
- employee-service and department-service: Both services are defined in this file with build contexts and ports.
- networks: A custom network
microservices-net
is created so the services can communicate with each other.
Step 5: Build and Run Docker Compose
In the root directory of your project (where the docker-compose.yml
file is located), run the following command to build and start the services:
docker-compose up --build
This command will:
- Build the Docker images for
employee-service
anddepartment-service
. - Start both services and connect them through the custom Docker network.
Step 6: Test the Microservices
Once the services are running, you can test them using a browser or Postman.
- employee-service: http://localhost:8081/employees/1
- department-service: http://localhost:8082/departments/1
You should see a response from department-service
that includes employee details fetched from employee-service
.
Conclusion
You have successfully created and deployed two Spring Boot microservices (employee-service
and department-service
) using Docker Compose. This architecture allows for easy scaling and isolation of services, making it perfect for microservices applications.
Next Steps:
- Add database integration (e.g., MySQL) to the services.
- Implement service discovery using tools like Spring Cloud Netflix Eureka.
Comments
Post a Comment
Leave Comment