Deploy Spring Boot to OpenShift
Learn how to deploy a Spring Boot application to OpenShift step by step using Docker, OpenShift CLI, Developer Console, Deployment, Service, and Route with real-world enterprise examples.
Introduction
Deploying a Spring Boot application to OpenShift is one of the most common tasks for Java developers working in enterprise environments.
Instead of manually copying JAR files to servers, OpenShift automates the deployment process by packaging the application into a container, deploying it as Pods, exposing it through Services and Routes, and managing its lifecycle.
In this article, you'll deploy a Spring Boot REST API to OpenShift from start to finish.
Learning Objectives
By the end of this article, you will learn:
- Build a Spring Boot application
- Create a Docker image
- Push the image to a registry
- Deploy the image to OpenShift
- Create a Service
- Expose the application using a Route
- Verify deployment
- Troubleshoot common issues
- Enterprise deployment workflow
End-to-End Deployment Architecture
flowchart LR
DEV["Developer"]
GIT["Git Repository"]
CI["CI Pipeline (Tekton / Jenkins)"]
IMAGE["Container Image"]
REG["Image Registry"]
subgraph OCP["OpenShift Cluster"]
DEPLOY["Deployment"]
PODS["Application Pods"]
SVC["Service"]
ROUTE["Route"]
end
USER["End User"]
DEV --> GIT
GIT --> CI
CI --> IMAGE
IMAGE --> REG
REG --> DEPLOY
DEPLOY --> PODS
PODS --> SVC
SVC --> ROUTE
ROUTE --> USER
This is the deployment workflow followed in most enterprise applications.
Prerequisites
Install the following tools:
- Java 21
- Maven
- Docker or Podman
- OpenShift CLI (
oc) - OpenShift Cluster or OpenShift Local
- Git
Project Structure
springboot-openshift-demo
├── src
├── Dockerfile
├── pom.xml
├── deployment.yaml
├── service.yaml
├── route.yaml
└── README.md
Step 1 – Create Spring Boot Project
Generate a Spring Boot application using Spring Initializr.
Dependencies:
- Spring Web
- Spring Boot Actuator
Step 2 – Create REST API
@RestController
@RequestMapping("/api")
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Welcome to CodeWithVenu OpenShift!";
}
}
Run locally:
mvn spring-boot:run
Verify:
http://localhost:8080/api/hello
Step 3 – Package the Application
mvn clean package
Generated file:
target/springboot-openshift-demo.jar
Step 4 – Create Dockerfile
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
Step 5 – Build Docker Image
docker build -t springboot-openshift-demo:1.0 .
Verify:
docker images
Step 6 – Test Container Locally
docker run -p 8080:8080 springboot-openshift-demo:1.0
Open:
http://localhost:8080/api/hello
Always verify the application locally before deploying.
Step 7 – Push Image to Registry
Example:
docker tag springboot-openshift-demo:1.0 quay.io/demo/springboot-demo:1.0
docker push quay.io/demo/springboot-demo:1.0
OpenShift will later pull this image.
Deployment Flow
flowchart LR
DEV["Developer"]
GIT["Git Repository"]
PIPELINE["CI/CD Pipeline"]
REGISTRY["Container Registry"]
subgraph OCP["OpenShift Cluster"]
DEPLOY["Deployment"]
PODS["Pods"]
SERVICE["Service"]
ROUTE["Route"]
end
USER["End User"]
DEV --> GIT
GIT --> PIPELINE
PIPELINE --> REGISTRY
REGISTRY --> DEPLOY
DEPLOY --> PODS
PODS --> SERVICE
SERVICE --> ROUTE
ROUTE --> USER
Step 8 – Login to OpenShift
oc login https://api.cluster.example.com
Verify:
oc whoami
Step 9 – Create Project
oc new-project springboot-demo
Switch project:
oc project springboot-demo
Step 10 – Create Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-demo
spec:
replicas: 2
selector:
matchLabels:
app: springboot-demo
template:
metadata:
labels:
app: springboot-demo
spec:
containers:
- name: springboot-demo
image: quay.io/demo/springboot-demo:1.0
ports:
- containerPort: 8080
Deploy:
oc apply -f deployment.yaml
Step 11 – Verify Pods
oc get pods
Example:
springboot-demo-1 Running
springboot-demo-2 Running
Step 12 – Create Service
apiVersion: v1
kind: Service
metadata:
name: springboot-service
spec:
selector:
app: springboot-demo
ports:
- port: 80
targetPort: 8080
Deploy:
oc apply -f service.yaml
Service Architecture
flowchart LR
Service
--> Pod1
Service
--> Pod2
Service
--> Pod3
The Service automatically load balances requests.
Step 13 – Create Route
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: springboot-route
spec:
to:
kind: Service
name: springboot-service
Deploy:
oc apply -f route.yaml
Request Flow
sequenceDiagram
participant B as Browser
participant R as OpenShift Route
participant S as Service
participant P as Pod
participant A as Spring Boot App
B->>R: HTTP Request
R->>S: Route request
S->>P: Forward to healthy pod
P->>A: Call application
A-->>P: Application response
P-->>S: Pod response
S-->>R: Service response
R-->>B: HTTP Response
Step 14 – Verify Route
oc get routes
Example:
springboot-route.apps.cluster.example.com
Open in browser:
https://springboot-route.apps.cluster.example.com/api/hello
Verify Deployment
oc get deployment
oc get pods
oc get services
oc get routes
Everything should be in the Running state.
Scaling Application
Increase replicas:
oc scale deployment springboot-demo --replicas=5
Verify:
oc get pods
Auto Scaling Architecture
flowchart TD
USERS["Users"]
LB["Route / Load Balancer"]
HPA["Horizontal Pod Autoscaler"]
subgraph APP["Application Pods"]
POD1["Pod 1"]
POD2["Pod 2"]
POD3["Pod 3"]
POD4["Pod 4"]
POD5["Pod 5"]
end
USERS --> LB
LB --> HPA
HPA --> POD1
HPA --> POD2
HPA --> POD3
HPA --> POD4
HPA --> POD5
View Logs
oc logs pod-name
Follow logs:
oc logs -f pod-name
Access Pod Terminal
oc rsh pod-name
Useful commands:
env
pwd
ls
java -version
Rolling Update
Deploy a new image:
oc set image deployment/springboot-demo \
springboot-demo=quay.io/demo/springboot-demo:2.0
OpenShift updates Pods gradually without downtime.
Enterprise Banking Deployment
flowchart LR
DEV["Developer"]
GIT["Git Repository"]
JENKINS["Jenkins CI/CD"]
IMAGE["Docker Image"]
QUAY["Quay Registry"]
subgraph OCP["OpenShift Cluster"]
DEPLOY["Deployment"]
POD1["Payment Pod 1"]
POD2["Payment Pod 2"]
SVC["Service"]
ROUTE["Route"]
end
USERS["Customers"]
DEV --> GIT
GIT --> JENKINS
JENKINS --> IMAGE
IMAGE --> QUAY
QUAY --> DEPLOY
DEPLOY --> POD1
DEPLOY --> POD2
POD1 --> SVC
POD2 --> SVC
SVC --> ROUTE
ROUTE --> USERS
Benefits:
- Zero downtime
- Auto scaling
- Rollback support
- Secure deployment
- Monitoring
- High availability
Common Deployment Issues
ImagePullBackOff
Cause:
- Incorrect image name
- Authentication issue
Solution:
- Verify registry
- Check image pull secret
CrashLoopBackOff
Cause:
- Application startup failure
Solution:
oc logs pod-name
Route Not Accessible
Verify:
oc get routes
Ensure the Service selector matches the Deployment labels.
Pod Pending
Possible causes:
- Insufficient CPU
- Insufficient Memory
- Node unavailable
Best Practices
- Use health probes.
- Define CPU and memory requests.
- Store configuration in ConfigMaps.
- Store credentials in Secrets.
- Use rolling deployments.
- Enable Horizontal Pod Autoscaler.
- Use immutable image tags.
- Never deploy directly to Production without testing.
Summary
In this article, you learned how to deploy a Spring Boot application to OpenShift from end to end.
Key steps included:
- Building the application
- Creating a Docker image
- Pushing the image to a registry
- Deploying to OpenShift
- Creating a Service
- Exposing a Route
- Verifying the deployment
- Scaling the application
- Monitoring logs
- Troubleshooting common issues
This deployment workflow is widely used in enterprise environments and forms the foundation for cloud-native Java applications.
Interview Questions
- What are the steps to deploy a Spring Boot application to OpenShift?
- Why do we need a Docker image?
- What is the purpose of a Deployment?
- Why is a Service required?
- What is the role of a Route?
- How do you scale a Deployment?
- How do you view Pod logs?
- What causes
ImagePullBackOff? - What is a rolling update?
- How does OpenShift ensure high availability?
Comments
Share a question, correction, or practical insight about this article.
Checking login status...
Loading approved comments...