# K8S + MiniKube+ Docker +Spring Boot REST API example

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1686465529986/baea8d46-35cd-46b7-9e81-176e1209bb00.jpeg align="center")

## Introduction:

Containerization has revolutionized software development and deployment by providing a consistent and scalable environment for running applications. In this article, we will explore how to develop a Spring Boot application, containerize it using Docker, and deploy it on a local Minikube cluster. Minikube is a lightweight Kubernetes implementation that allows you to set up a local Kubernetes environment for testing and development purposes. Let's dive in and learn how to get started!

### Prerequisites:

Before we begin, make sure you have the following prerequisites installed on your development machine:

1. Java Development Kit (JDK) 13 or higher
    
2. Docker
    
3. Minikube
    
4. kubectl (Kubernetes command-line tool)
    

### Setup Application:

**Step 1:**

Set up the Spring Boot Application

To begin, let's create a simple Spring Boot application. You can either use an existing application or create a new one using Spring Initializr. Make sure your application runs successfully by executing it locally.

* Create a new Spring Boot project or use an existing one.
    
* Create a new Java class named `UserController` that will handle the REST API endpoints. Add the following code:
    

Create a `User` class to represent the user entity. Add the following code:

```java
public class User {
    private Long id;
    private String name;
    private String email;

    // Getters and setters

    // Constructors
}
```

```java
@RestController
@RequestMapping("/api/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/")
    public ResponseEntity<List<User>> getUsers() {
        List<User> users = userService.getAllUsers();
        return ResponseEntity.ok(users);
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable("id") Long id) {
        User user = userService.getUserById(id);
        if (user != null) {
            return ResponseEntity.ok(user);
        } else {
            return ResponseEntity.notFound().build();
        }
    }

    @PostMapping("/")
    public ResponseEntity<User> createUser(@RequestBody User user) {
        User createdUser = userService.createUser(user);
        return ResponseEntity.ok(createdUser);
    }

    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable("id") Long id, @RequestBody User user) {
        User updatedUser = userService.updateUser(id, user);
        if (updatedUser != null) {
            return ResponseEntity.ok(updatedUser);
        } else {
            return ResponseEntity.notFound().build();
        }
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable("id") Long id) {
        boolean deleted = userService.deleteUser(id);
        if (deleted) {
            return ResponseEntity.noContent().build();
        } else {
            return ResponseEntity.notFound().build();
        }
    }
}
```

In this example, the `UserController` class injects an instance of `UserService` via constructor injection. The service layer is responsible for processing business logic and interacting with the repository DAO.

Create a new Java interface named `UserService` defines the service layer methods. Add the following code:

```java
public interface UserService {

    List<User> getAllUsers();

    User getUserById(Long id);

    User createUser(User user);

    User updateUser(Long id, User user);

    boolean deleteUser(Long id);
}
```

The `UserService` interface declares the methods for retrieving all users, retrieving a user by ID, creating a new user, updating a user by ID, and deleting a user by ID.

Create a new Java class named `UserServiceImpl` implements the `UserService` interface. Add the following code:

```java
@Service
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;

    public UserServiceImpl(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    @Override
    public User getUserById(Long id) {
        Optional<User> userOptional = userRepository.findById(id);
        return userOptional.orElse(null);
    }

    @Override
    public User createUser(User user) {
        return userRepository.save(user);
    }

    @Override
    public User updateUser(Long id, User user) {
        Optional<User> userOptional = userRepository.findById(id);
        if (userOptional.isPresent()) {
            User existingUser = userOptional.get();
            existingUser.setName(user.getName());
            existingUser.setEmail(user.getEmail());
            return userRepository.save(existingUser);
        } else {
            return null;
        }
    }

    @Override
    public boolean deleteUser(Long id) {
        Optional<User> userOptional = userRepository.findById(id);
        if (userOptional.isPresent()) {
            userRepository.delete(userOptional.get());
            return true;
        } else {
            return false;
        }
    }
}
```

The `UserServiceImpl` class implements the `UserService` methods by interacting with the `UserRepository` DAO.

Create a new Java interface named `UserRepository` that extends `JpaRepository<User, Long>`. Add the following code:

```java
public interface UserRepository extends JpaRepository<User, Long> {
}
```

The `UserRepository` interface extends the `JpaRepository` the interface provided by Spring Data JPA, which provides generic CRUD operations for the `User` entity.

Run the Spring Boot application, and the REST API endpoints will be available at the following URLs:

* GET: [**http://localhost:8080/api/users/**](http://localhost:8080/api/users/) (Get all users)
    
* GET: [**http://localhost:8080/api/users/{id}**](http://localhost:8080/api/users/{id}) (Get user by ID)
    
* POST: [**http://localhost:8080/api/users/**](http://localhost:8080/api/users/) (Create a new user)
    
* PUT: [**http://localhost:8080/api/users/{id}**](http://localhost:8080/api/users/{id}) (Update user by ID)
    
* DELETE: [**http://localhost:8080/api/users/{id}**](http://localhost:8080/api/users/{id}) (Delete user by ID)
    

The service layer (`UserServiceImpl`) will handle the business logic and interact with the repository DAO (`UserRepository`) to perform CRUD operations on users.

**Step 2:**

Containerize the Spring Boot Application To containerize our Spring Boot application, we will create a Dockerfile. Create a file named `Dockerfile` in the root directory of your project and add the following content:

```bash
FROM adoptopenjdk:13-jre-hotspot
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
```

This Dockerfile uses an OpenJDK 11 base image, sets the working directory to `/app`, copies the Spring Boot application's JAR file into the container, exposes port 8080, and defines the command to run the application.

**Step 3:**

Build and Push the Docker Image Next, open a terminal and navigate to the root directory of your Spring Boot project. Build the Docker image by running the following command:

```bash
docker build -t my-spring-app .
```

Once the image is built successfully, you can optionally push it to a container registry such as Docker Hub for easier access in your Minikube cluster.

**Step 4:**

Set up and Start Minikube Ensure that Minikube is installed on your machine. Start Minikube by running the following command:

```bash
minikube start
```

This will create and start a local Kubernetes cluster using the Minikube driver.

**Step 5:**

Deploy the Spring Boot Application Now it's time to deploy our Spring Boot application to the Minikube cluster. We'll create a Kubernetes deployment and a service to expose the application.

First, create a file named `deployment.yaml` and add the following content:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-spring-app-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-spring-app
  template:
    metadata:
      labels:
        app: my-spring-app
    spec:
      containers:
        - name: my-spring-app-container
          image: my-spring-app
          ports:
            - containerPort: 8080
```

This YAML file defines a deployment with a single replica, a selector, and a pod template that runs our containerized Spring Boot application.

Next, create a file named `service.yaml` and add the following content:

```bash
apiVersion: v1
kind: Service
metadata:
  name: my-spring-app-service
spec:
  selector:
    app: my-spring-app
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
  type: NodePort
```

This YAML file defines a service that exposes our application on a NodePort, allowing us to access it from our local machine.

Apply both YAML files to the Minikube cluster by running the following commands:

```bash
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
```

**Step 6:**

Access the Spring Boot Application To access the deployed Spring Boot application, find the NodePort assigned to the service. Run the following command:

```bash
minikube service my-spring-app-service --url
```

This will provide you with a URL that you can use to access your application from a web browser or via cURL.

## Conclusion:

In this article, we walked through the process of developing a Spring Boot application, containerizing it using Docker, and deploying it on a local Minikube cluster. Containerization provides a reliable and scalable environment for running applications, while Minikube offers a convenient way to test and develop Kubernetes deployments locally. By following these steps, you can start building and deploying your own containerized Spring Boot applications using Minikube and Kubernetes.

I hope this helps, you!!

**More such articles:**

[https://medium.com/techwasti](Link)

[https://www.youtube.com/@maheshwarligade](https://www.youtube.com/@maheshwarligade)

[https://www.techwasti.com/](Link)

\==========================\*\*=========================

**If this article adds any value to you then please clap and comment.**

**Let’s connect on** [**Stackoverflow**](http://stackoverflow.com/users/3187349/maheshwar-ligade)**,** [**LinkedIn**](https://in.linkedin.com/in/maheshwar-ligade-14447841)**, &** [**Twitter**](https://twitter.com/MaheshwarLigade)**.**
