WittCode💻

How to Deploy a React App with Kubernetes

By

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

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.