React + Spring Boot Deployment(The Kubernetes Way)
In this article, we’ll go through a possible way to deploy Your Spring Boot application with React Front-end, given that it is being deployed to a Kubernetes Cluster. We will take advantage of the Dns feature of kubernetes that helps us to communicate between services and pods.
Without Kubernetes, you could still combine your Spring Boot application with A React Front-end. This involves building a static build of your React application and putting it in the /classes/public
folder. The the resulting jar file contains the React Application as the Front-end of the Spring boot application. The full process is describe in this article.
This article provides an option if you would like to use the Unsupported Features of the next.js
static export.
Some important assumptions for this to work
1. Your Spring Boot Back-end routes are prefixed with a specific prefix, For example: /api
2. Your React Front-end routes would fill the remaining routes.
3. This is a bit experimental and would probably work more for a personal project, rather than for a big project.
For our use case, we don’t need to update our pom.xml to add some build plugins.
So we’ll just need to deploy the Spring boot application separately and deploy the React js application separately.
Frontend Proxy
The proxy url for the backend application is http://name-of-backend-service
For a regular react.js application, adding "proxy": "http://name-of-backend-service
, would be all that is needed, but for a next.js
, you would need to update the next.config.js
file and add a rewrite like so:
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
async rewrites() {
return {
fallback: [
{
source: '/api/:path*',
destination: `http://name-of-backend-service/api/:path*`
}
]
}
}
}module.exports = nextConfig
Kubernetes Definition Files
Now the Interesting part:
The ingress definition file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: #INGRESS_NAME#
namespace: #NAMESPACE#
spec:
rules:
- host: example.com
http:
paths:
- backend:
service:
name: name-of-frontend-service
port:
number: 3000
path: /
pathType: Prefix
React Js Definition File
apiVersion: v1
kind: Service
metadata:
name: name-of-frontend-service
namespace: #NAMESPACE#
spec:
ports:
- port: 3000
targetPort: 3000
selector:
app: frontend
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: #NAMESPACE#
spec:
selector:
matchLabels:
app: frontend
replicas: 1
template:
metadata:
labels:
app: frontend
spec:
containers:
- image: #IMAGE_FRONTEND#
name: frontend
imagePullPolicy: Always
ports:
- containerPort: 3000
Spring Boot Definition file:
apiVersion: v1
kind: Service
metadata:
name: name-of-backend-service
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
selector:
matchLabels:
app: backend
replicas: 1
template:
metadata:
labels:
app: backend
spec:
containers:
- image: #IMAGE_BACKEND#
name: backend
ports:
- containerPort: 8080
Conclusion
With this, our application is now taking advantage of Kubernetes’ DNS for Services and Pods.
A git repo for the demo project can be found here.