Hello everyone,
As developers, we know that writing an application is only half the battle. The other half is packaging, rolling out and operating them reliably. This is where the microservice stack with Spring Boot, Docker and Kubernetes comes into play.
In this guide, we’ll build a simple Spring Boot microservice and make it production-ready in two steps: First, we’ll package it into a Docker image for local execution. Then we take it to the next level and deploy it on Kubernetes.
The article is structured so that you can follow the first part even without a Kubernetes cluster.
Note: The code was generated with Warp for testing purposes. Therefore, there may be slight discrepancies between the snippets in this post and the actual code in the repository.
Part 1: Your Spring Boot microservice with Docker
1. Write the application
We start with a simple REST API that returns a greeting.
Required Dependencies:
- Spring Web
- Spring Boot DevTools
- Lombok
Create a new Spring Boot project with these dependencies and add the following classes:
src/main/java/com/example/demo/controller/GreetingController.java
package com.example.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
@GetMapping("/hello")
public String sayHello(@RequestParam(value = "name", defaultValue = "World") String name) {
return String.format("Hello, %s!", name);
}
}
This controller creates an endpoint /hello that accepts an optional name parameter. If no name is passed, “World” is used by default.
2. Create the Dockerfile
In order to run our application with Docker, we need a Dockerfile. Place this file in the root directory of your project.
Dockerfile
# Wir nutzen das offizielle OpenJDK 17-JDK-Image als Basis
FROM openjdk:17-jdk-slim
# Metadaten fuer unser Image
LABEL authors="Julian Paul"
LABEL description="Mein erster Spring Boot Microservice"
# Wir definieren ein Argument fuer den JAR-Dateinamen
ARG JAR_FILE=target/*.jar
# Kopiere die kompilierte JAR-Datei in den Container
COPY ${JAR_FILE} app.jar
# Definiere das Arbeitsverzeichnis
WORKDIR /
# Starte die Anwendung, wenn der Container laeuft
ENTRYPOINT ["java", "-jar", "app.jar"]
This Dockerfile is lightweight and efficient. It copies the finished compiled JAR file into the image, which speeds up the build process because the compilation occurs outside of Docker.
3. Build the application and package it as a Docker image
Open a terminal in your project directory.
- Build Spring Boot application:
./mvnw package
```
This command compiles the code, runs the tests and creates the `.jar` file in the `target/` directory.
2. **Build Docker Image:**
```bash
docker build -t my-microservice .
```
With `docker build` we build the image from the `Dockerfile`. `-t my-microservice` tags the image with the name `my-microservice` and `.` indicates that the `Dockerfile` is in the current directory.
3. **Run Docker container:**
```bash
docker run -p 8080:8080 my-microservice
```
* `docker run` starts a container.
* `-p 8080:8080` maps port 8080 of the container to port 8080 on your local machine.
* `my-microservice` is the name of the image we just built.
If everything went well, your application can now be accessed at [http://localhost:8080/hello](https://www.google.com/search?q=http://localhost:8080/hello).
-----
## Part 2: Deployment on Kubernetes
If you want your microservice to go live, you need a scalable platform. Kubernetes is the gold standard for this.
**Important:** For this part you need a running Kubernetes cluster (e.g. with [Minikube](https://minikube.sigs.k8s.io/docs/start/), [Docker Desktop](https://docs.docker.com/desktop/kubernetes/) or a cloud provider like AWS EKS, Google GKE).
### 1\. Push the Docker image to a registry
In order for Kubernetes to find your image, it must be stored in a registry. We use Docker Hub for this.
1. **Log in to Docker Hub:**
```bash
docker login
```
2. **Tag image:**
```bash
docker tag my-microservice:latest dein-dockerhub-username/my-microservice:v1
```
Replace `your-dockerhub-username` with your actual Docker Hub username.
3. **Image pushen:**
```bash
docker push dein-dockerhub-username/my-microservice:v1
```
### 2\. Write the deployment manifest
A deployment manifest describes how Kubernetes should roll out your application. Create a file called `deployment.yaml`.
**`deployment.yaml`**
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-microservice-deployment
labels:
app: my-microservice
spec:
replicas: 1 # Starte mit einer Instanz (Pod)
selector:
matchLabels:
app: my-microservice
template:
metadata:
labels:
app: my-microservice
spec:
containers:
- name: my-microservice
image: dein-dockerhub-username/my-microservice:v1 # Hier dein Image-Pfad
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: my-microservice-service
spec:
selector:
app: my-microservice
type: LoadBalancer # Oder NodePort, je nach Umgebung
ports:
- protocol: TCP
port: 8080
targetPort: 8080
- Deployment: Ensures that the specified number of pod instances are always running.
- Service: Allows access to your pods by routing requests to them. The
LoadBalancertype creates an external IP address (in cloud environments). For local setups like Minikube,NodePortis often easier.
3. Deploy to Kubernetes
Open a terminal with access to your cluster and apply the manifest:
kubectl apply -f deployment.yaml
The kubectl tool reads your deployment.yaml and tells Kubernetes to deploy your application.
4. Launch the application on Kubernetes
Find your service’s external IP address:
kubectl get services my-microservice-service
Under the “EXTERNAL-IP” column you will find the address at which your application can be reached.
Conclusion
Congratulations! You have just packaged your first Spring Boot application into a Docker image and deployed it on Kubernetes. This is the foundational stack for modern microservices. From here you can deepen your knowledge and explore advanced concepts such as ConfigMaps, Secrets, Ingress and Helm Charts.
Required dependencies
For the Spring Boot project in pom.xml (Maven) or build.gradle (Gradle) you need the following dependencies:
Maven (pom.xml)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
Gradle (build.gradle)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
![[EN] Dein Erster Microservice Stack](/images/DeinersterMicroservice-Stack-BlogHeader.png)