Spring Boot Microservices with Docker Tutorial

author : Sai K

In this tutorial, we will create a simple Spring Boot microservices architecture with two services: employee-

service and department-service. We will containerize these services using Docker and manage them with Docker

Compose.


Prerequisites

Before we start, ensure you have the following:

  • Java Development Kit (JDK) installed

  • Apache Maven installed

  • Docker installed

  • Docker Compose installed

  • An IDE (such as IntelliJ IDEA, Eclipse, or VS Code) installed

Overview of the Microservices

We will create two Spring Boot microservices:

1.Employee Service: Manages employee information.

2. Department Service: Manages department information.

Additionally, we will create an API Gateway to route requests to these services.

Step 1: Creating the Microservices

1.1 Create the Employee Service

Open Spring Initializr:

Go to Spring Initializr in your web browser.

2.Configure Project Metadata:

  • Project: Maven Project

  • Language: Java

  • Spring Boot: Select the latest version of Spring Boot

  • Group: com.example

  • Artifact: employee-service

  • Name: employee-service

  • Description: Employee Service

  • Package Name: com.example.employeeservice

  • Packaging: Jar

  • Java Version: 17 (or your preferred version)

  • Click Next.

3.Select Dependencies:

  • On the Dependencies screen, select the dependencies you need:
    • Spring Web

    • Spring Data JPA

    • H2 Database

  • Click Next.
  • 4.Generate the Project:

    • Click Generate to download the project zip file.

    • Extract the zip file to your desired location.

    5.Open the Project in Your IDE:

    • Open your IDE and import the project as a Maven project.

    1.1.1 Update application.properties

    Open the application.properties file located in the src/main/resources directory and add the following configuration:

    
    server.port=8081
    spring.datasource.url=jdbc:h2:mem:testdb
    spring.datasource.driverClassName=org.h2.Driver
    spring.datasource.username=sa
    spring.datasource.password=password
    spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
    spring.h2.console.enabled=true
    spring.jpa.hibernate.ddl-auto=update
                           

    1.1.2 Create Employee Entity

    Create an Employee entity class in the com.example.employeeservice.model package:

    
    package com.example.employeeservice.model;
    
    import jakarta.persistence.Entity;
    import jakarta.persistence.GeneratedValue;
    import jakarta.persistence.GenerationType;
    import jakarta.persistence.Id;
    
    @Entity
    public class Employee {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String name;
        private String department;
    
        // Getters and Setters
    }

    1.1.3 Create Employee Repository

    Create an EmployeeRepository interface in the com.example.employeeservice.repository package:

    
        package com.example.employeeservice.repository;
    
    import com.example.employeeservice.model.Employee;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface EmployeeRepository extends JpaRepository {
    }
    

    1.1.4 Create Employee Controller

    Create an EmployeeController class in the com.example.employeeservice.controller package:

    
        package com.example.employeeservice.controller;
    
    import com.example.employeeservice.model.Employee;
    import com.example.employeeservice.repository.EmployeeRepository;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    @RestController
    @RequestMapping("/employees")
    public class EmployeeController {
    
        private final EmployeeRepository employeeRepository;
    
        @Autowired
        public EmployeeController(EmployeeRepository employeeRepository) {
            this.employeeRepository = employeeRepository;
        }
    
        @GetMapping
        public List getAllEmployees() {
            return employeeRepository.findAll();
        }
    
        @PostMapping
        public Employee createEmployee(@RequestBody Employee employee) {
            return employeeRepository.save(employee);
        }
    }
    

    Step 1: Creating the Microservices

    1.1 Create the Employee Service

    Open Spring Initializr:

    Go to Spring Initializr in your web browser.

    2.Configure Project Metadata:

    • Project: Maven Project

    • Language: Java

    • Spring Boot: Select the latest version of Spring Boot

    • Group: com.example

    • Artifact:api-gateway

    • Name:api-gateway

    • Description:API Gateway

    • Package Name: com.example.apigateway

    • Packaging: Jar

    • Java Version: 17 (or your preferred version)

    • Click Next.

    3.Select Dependencies:

  • On the Dependencies screen, select the dependencies you need:
    • Spring Cloud Gateway

    • Spring Boot DevTools

  • Click Next.
  • 4.Generate the Project:

    • Click Generate to download the project zip file.

    • Extract the zip file to your desired location.

    5.Open the Project in Your IDE:

    • Open your IDE and import the project as a Maven project.

    1.3.1 Update application.yml

    Create an application.yml file in the src/main/resources directory and configure it as follows:

    
            server:
      port: 8080
    
    spring:
      application:
        name: api-gateway
    
      cloud:
        gateway:
          routes:
            - id: employee_service
              uri: http://localhost:8081
              predicates:
                - Path=/employees/**
            - id: department_service
              uri: http://localhost:8082
              predicates:
                - Path=/departments/**
          

    Step 2: Containerizing the Microservices with Docker

    2.1 Create Dockerfiles

    Create a Dockerfile in the root directory of each microservice (employee-service, department-service, and api-

    gateway).


    2.1.1 Employee Service Dockerfile

    
            # Start with a base image containing Java runtime
    FROM openjdk:17-jdk-alpine
    
    # Add a volume pointing to /tmp
    VOLUME /tmp
    
    # Make port 8081 available to the world outside this container
    EXPOSE 8081
    
    # The application's jar file
    ARG JAR_FILE=target/employee-service-0.0.1-SNAPSHOT.jar
    
    # Add the application's jar to the container
    ADD ${JAR_FILE} app.jar
    
    # Run the jar file
    ENTRYPOINT ["java","-jar","/app.jar"]
          

    2.1.2 Department Service Dockerfile

    
            # Start with a base image containing Java runtime
    FROM openjdk:17-jdk-alpine
    
    # Add a volume pointing to /tmp
    VOLUME /tmp
    
    # Make port 8082 available to the world outside this container
    EXPOSE 8082
    
    # The application's jar file
    ARG JAR_FILE=target/department-service-0.0.1-SNAPSHOT.jar
    
    # Add the application's jar to the container
    ADD ${JAR_FILE} app.jar
    
    # Run the jar file
    ENTRYPOINT ["java","-jar","/app.jar"]
          

    2.1.3 API Gateway Dockerfile

    
    # Start with a base image containing Java runtime
    FROM openjdk:17-jdk-alpine
    
    # Add a volume pointing to /tmp
    VOLUME /tmp
    
    # Make port 8080 available to the world outside this container
    EXPOSE 8080
    
    # The application's jar file
    ARG JAR_FILE=target/api-gateway-0.0.1-SNAPSHOT.jar
    
    # Add the application's jar to the container
    ADD ${JAR_FILE} app.jar
    
    # Run the jar file
    ENTRYPOINT ["java","-jar","/app.jar"]
    

    2.2 Build Docker Images

    Open a terminal and navigate to each project's root directory, then build the Docker images using the following

    commands:

    2.2.1 Employee Service

    
        mvn clean package
        docker build -t employee-service .
    

    2.2.2 Department Service

    
     mvn clean package
    docker build -t department-service .
    

    2.2.3 API Gateway

    
        mvn clean package
        docker build -t api-gateway .
    

    Step 3: Managing Containers with Docker Compose

    3.1 Create docker-compose.yml

    In the root directory of your project (outside all microservice directories), create a docker-compose.yml file:

    
        version: '3.8'
    
    services:
      employee-service:
        image: employee-service
        container_name: employee-service
        ports:
          - "8081:8081"
    
      department-service:
        image: department-service
        container_name: department-service
        ports:
          - "8082:8082"
    
      api-gateway:
        image: api-gateway
        container_name: api-gateway
        ports:
          - "8080:8080"
        depends_on:
          - employee-service
          - department-service
    

    3.2 Run Docker Compose

    In the terminal, navigate to the directory containing the docker-compose.yml file and run the following command

    to start all services:

    docker-compose up

    Step 4: Testing the Application

    Once all services are up and running, you can test the application using a tool like Postman or your web browser.

    4.1 Access the Employee Service

    Open your browser or Postman and navigate to http://localhost:8080/employees. You should see the list of

    employees.

    4.2 Access the Department Services

    Open your browser or Postman and navigate to http://localhost:8080/departments. You should see the list of

    departments.

    Conclusion

    In this tutorial, we created a simple microservices architecture using Spring Boot. We containerized the

    microservices with Docker and managed them using Docker Compose. This setup provides a solid foundation for

    developing more complex microservices architectures and deploying them using Docker.

    Related Spring and Spring Boot Tutorials/Guides: