How to Deploy a React App with Kubernetes
Learn how to deploy a React App with Kubernetes. For this demonstration we will be running everything locally.
Table of Contents 📖
- Generating the React Bundle
- Creating the Nginx Image
- Kubernetes Deployment
- Services
- Accessing the Application
Generating the React Bundle
The React app bundle consists of the following files:
[object Object]
These files are generated by the npm command npm run build which uses Webpack to bundle the React app into a single file called bundle.js. The index.html file imports the bundle.js file which then creates the React application inside a div with the id of root.
Creating the Nginx Image
Lets create the Nginx Docker image that creates this bundle and copies it over to Nginx to serve up.
FROM node:alpine AS build
WORKDIR /client
COPY package*.json .
RUN npm i
COPY . .
RUN npm run build
FROM nginx
COPY --from=build /client/dist /usr/share/nginx/html
Here we do a multi-stage build, the first stage generates the bundle and the second stage copies it over to the /usr/share/nginx/html directory. This is the default location nginx looks at when serving static content.
Kubernetes Deployment
A Kubernetes Deployment tells Kubernetes how to create Pods that house the Docker containers. In this instance, we are going to create a deployment to spin up a Pod to house the Nginx Docker container that serves up our React app. We can create a deployment object using a Kubernetes YAML file.
INFO: Pods are the smallest deployable unit of computing that Kubernetes can create and manage. They are a group of one or more containers.
apiVersion: apps/v1 # The API version of Kubernetes to create the Object.
kind: Deployment # The kind of object we want to create.
metadata: # Data that helps uniquely identify the object.
name: my-react-app-deployment
spec: # The desired state of the object
selector: # Tells the deployment to match the pod according to the label.
matchLabels: # Says what pods the deployment will apply to
app: my-react-app-label
replicas: 3 # Number of pods to make for the deployment.
template: # A podTemplate. Describes a pod that is launched.
metadata:
labels: # Label for the pod that the deployment is deploying
app: my-react-app-label
spec: # The desired state of the pod
containers: # List of containers belonging to the pod
- name: my-react-app-c
image: localhost:6500/my-react-app-i # Container image name
ports: # List of ports to expose from the container
- containerPort: 80 # Number of port to expose on the pod's IP address
WARNING: Note that we are getting the container from a local repository running on localhost:6500. Switch this line with the registry you are using.
Create the deployment by running the following command:
kubectl apply -f deployment.yaml
deployment.apps/my-react-app-deployment created
This command creates the deployment. Check that the deployment was created by running the following command:
kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
my-react-app-deployment 3/3 3 3 11s
- Name - lists the names of the Deployments in the namespace.
- Ready - Displays how many replicas of the application are available to the users.
- UP-TO-DATE - Displays the number of replicas that have been updated to acheive the desired state, the latest Pod template.
- AVAILABLE - Displays the number of available replicas.
- AGE - How long the application has been running.
Services
Now lets create a Kubernetes Service to expose the Pods to the outside world.
apiVersion: v1
kind: Service # Exposing a network application running as one or more Pods in the Cluster.
metadata: # Data that helps uniquely identify the object.
name: load-balancer
spec:
type: LoadBalancer # Exposes the Service externally using a load balancer.
ports:
- port: 80
protocol: TCP
selector: # The set of pods targeted by the Service.
app: my-react-app-label # Needs to match deployment.yaml
Create the service by running the following command:
kubectl apply -f ./service.yaml
service/load-balancer created
This command creates the service. We can check that the service was created by running the following command:
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d20h
load-balancer LoadBalancer 10.103.108.91 localhost 80:30762/TCP 76s
This command lists all services in the namespace.
Accessing the Application
We can now access the react application on localhost:80. To demonstrate, lets send a cURL request there.
curl localhost:80
<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>React App</title><script defer="defer" src="bundle.js"></script></head><body><div id="root"></div></body></html>
Accessing the application in the browser will execute the bundle.js file, displaying the React app.