How to Deploy a React App to a Kubernetes Cluster
Kubernetes has more advanced deployment features such as blue-green and canary deployments. Kubernetes easily handles peak traffic.
Kubernetes is a gold standard in the industry for deploying containerized applications in the cloud. Many cloud providers (e.g., Google Cloud, AWS, etc.) provide services for deploying applications to the cloud using Kubernetes, or their environment.
Here are some of the reasons that we recommend you choose Kubernetes to deploy your React application:
- Kubernetes provides us with a standardized and unified deployment system for all cloud providers.
- Kubernetes has more advanced deployment features such as blue-green and canary deployments.
- Kubernetes easily handles peak traffic.
- Kubernetes’ deployment architecture plays a vital role in minimizing downtime when you have the right strategy in place.
- Kubernetes helps your DevOps team alleviate problems that arise from a hybrid cloud-based strategy.
- Kubernetes has a very special service discovery feature, so developers don’t have to worry about discovery/managing everything themselves.
- Kubernetes enables companies to solve common problems quickly and efficiently.
React
React is an open-source single-page application developed by Facebook and released in 2013. React is a Javascript library for DOM manipulation and the “V” in the MVC paradigm, where you can use it as a front end development. It’s a component-based library that uses Javascript to build its front end applications. It’s also very easy to understand, can handle complex UI, and is highly responsive. The data flow in React is one dimensional - we can pass data from parent component to a child component thru props.
Prerequisites:
- Docker installation:
https://docs.docker.com/docker-for-windows/install/ - Kubernetes can be enabled as we have discussed below, for installing Minikube:
https://kubernetes.io/docs/tasks/tools/install-minikube/ - For Kubectl installation:
https://kubernetes.io/docs/tasks/tools/install-kubectl/ - Install Node js:
- https://nodejs.org/en/
- Node version >=8
- Npm version >=5
In this guide, we’ll look at how we can deploy a React application easily to a Kubernetes cluster.
We’ll be using the local Kubernetes cluster throughout this guide and once you have Docker installed, let's get started.
Creating a React Application
Step 1: Creating the React Application
We’ll start with a basic React application that we create with the create-react-app command:
$ npx create-react-app hello
Result:
Creating a new React app in C:\Users\pc\Desktop\react\hello.
Installing packages. This might take some minutes.
Installing react, react-dom, and react-scripts…
> core-js@2.6.11 postinstall C:\Users\pc\Desktop\react\hello\node_modules\babel-runtime\node_modules
\core-js
> node -e "try{require('./postinstall')}catch(e){}"> core-js@3.6.5 postinstall
C:\U Users\pc\Desktop\react\hello\node_modules\core-js
> node -e "try{require('./postinstall')}catch(e){}"
> core-js-pure@3.6.5 postinstall C:\Users\pc\Desktop\react\hello\node_modules\core-js-pure
> node -e "try{require('./postinstall')}catch(e){}
+ react-scripts@3.4.1
+ react-dom@16.13.1
+r react@16.13.1
Added added 1625 packages from 750 contributors and audited 1629 packages in
npx-create -react app is a command that will install all the required packages for building single-page React applications.
After npx create-react-app we define the name of the application, here we are using hello.
The create react app does not handle any backend stuff or databases, it just creates a front end structure so we can use it with any suitable backend.
It provides you with a nice developer experience, and it also helps in the optimization of your app.
Step 2: Starting React Application
$ npm start
The above command starts your react application.
Go to your browser and access the react application at your localhost:3000
Step 3: Optimizing React Application
We need the optimized version of React to deploy to Kubernetes.
$ npm run-script build
This command will create a build folder, and then create the build version in the build directory.
Result:
> npm run-script build
> todo@0.1.0 build C:\Users\pc\Desktop\_igetintopc.com_Fix\idlex-1.18\react \hello
> react-scripts build
Creating an optimized production build...
File sizes after gzip:
40.25 KB build\static\js\2.d4205dc2.chunk.js
937 B build\static\js\main.b56f7c61.chunk.js
773 B build\static\js\runtime-main.83c66be5.js
409 B build\static\css\main.0202d408.chunk.css
The project was built assuming it is hosted at the server root.
You can control this with the homepage field in your package.json.
For example, add this to build it for GitHub Pages:
"homepage" : "http://myname.github.io/hello",
Dockerizing The Application
For deployment, we’ll package our application within a container. Kubernetes supports many different container engines, here we’ll use Docker (which is widely used).
For the creation of a Docker container, we’ll make a docker file in our application. The file used instructs docker how to build images step by step. Dockerfile can contain an OS type server name application to use, or any command to run inside the container.
Docker file has to be in the root folder of your project and named as Dockerfile.
1. Using Node
FROM node:10.4.3
WORKDIR /usr/src/app
COPY package*.json ./
ADD package.json /usr/src/app/package.json
RUN npm install
RUN npm install react-scripts@1.1.0 -g
COPY . .
EXPOSE 3000
CMD ["npm ","start"];
Here, we’ll be using Nginx for the React application. You can either use node or Nginx as we’ve shown above in both images. In this tutorial, we’ll be using Nginx, so here is our Dockerfile view.
2. Using Nginx
FROM nginx:1.19.0
COPY build/ /usr/share/nginx/html
The Docker pulls everything from nginx:1.19.0 Dockerfile and copies React to the container directory.
Now your React app is ready. To build Docker image, type the below command:
$ docker build -t hello .
Result
Sending build context to Docker daemon 162.7MB
Step 1/2 : FROM nginx:1.17
---> 9beeba249f3e
Step 2/2 : COPY build/ /usr/share/nginx/html
---> Using cache
---> 4fb641a64161`
Successfully built 4fb641a64161
Successfully tagged hello:latest
Connecting to the Kubernetes Cluster
To start the Kubernetes cluster on your local machine, open the Docker Desktop application and go to the Kubernetes tab. Check this box to enable Kubernetes support. After enabling, it will take some time to create your cluster.
We’ll use docker-for-desktop as a default context to Kubernetes cluster.
kubectl config use-context docker-for-desktop
> Switch to context "docker-for-desktop".
The following command will be used to get nodes of the cluster:
$ kubectl get nodes
Result:
NAME STATUS ROLES AGE VERSION
docker-desktop Ready master 33h v1.16.6-beta.0
The following command will be used to see the cluster information:
kubectl cluster-info
Result:
Kubernetes master is running at https://kubernetes.docker.internal:6443
KubeDNS is running at https://kubernetes.Docker.internal:6443/api/v1/namespaces
/kube-system/services/kube-dns:dns/prox
Uploading the Docker Image
Now we’ll upload the image to docker registry so that we can pull the Docker image from anywhere.
Next, we’ll start the docker container with the following command and expose port 5000 using the image hello.
docker run -d -p 5000:5000 --restart=always --name hello registry:2
For uploading the Docker image, use your hostname after tag and your port, here hello refers to the hostname.
docker tag hello zarakmughal/hello
Now push the image to Docker registry:
docker push zarakmughal/hello
The push refers to repository [localhost:5000/hello]
180e471f57a2: Pushed
2f4accd375d9: Pushing
6c7de695ede3: Pushed [======================================>] 44.81MB/57.56
Bffc9b21953f4: Pushing [=========================> ] 35.75MB/69.21MB
Now the application is ready to be deployed on the Kubernetes cluster.
Deploying the React Application
Here, we’ll use a yaml file to create deployment and service. The Yaml file contains the description of every Kubernetes object (service, pods, deployment, etc.) The Kubernetes entity makes sure our application will have as many replicas (parallel pods) as we define. We can also define the type of Docker image we want to use, what type of ports are used, and metadata for our application:
kind: Deployment
apiVersion: apps/v1
metadata:
name: hello
spec:
replicas: 2
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
image: zarakmughal/hello
imagePullPolicy: Always
ports:
- containerPort: 80
restartPolicy: Always
As happened with deployment, we won't be able to access our application just yet. So, we’ll use a service to expose our application. By using a service, we can expose the ports to the cluster/outside.
Of the several types of Kubernetes service, we’ll be using nodeport, which is the simplest one. The nodeport type will expose a defined port on every node in our Kubernetes cluster (with the local Kubernetes cluster, we just have one node) and map it to an application's port:
kind: Service
apiVersion: v1
metadata:
name: hello
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
nodePort: 31000
selector:
app: hello
We can add both the service and deployment into a single .yaml file. For separation, we’ll use ---. Here’s an example below to show you the deployment.yaml file - also, with an example of both files.
We will use deployment part here
---
We will use service part here
Now Deploying our Application to Kubernetes:
kubectl apply -f deployment.yaml
Result:
deployment.apps "hello" created
service "hello" created
Now check for running status with the below command:
kubectl get pods
Result:
NAME READY STATUS RESTARTS AGE
hello-bc9d4f9f5-68ck8 0/1 ImagePullBackOff 0 14m
hello-bc9d4f9f5-fgcfz 0/1 ImagePullBackOff 0 14m
kubectl get deployment
Result:
NAME READY UP-TO-DATE
hello 2/2 2 2 39s
kubectl get service
Result:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 32h
hello NodePort 10.104.172.125 80:31000/TCP 41m
Once all of that is completed, you can visit http://localhost:31000 on your machine. Now you should be able to see that your React application has been deployed on Kubernetes.
After we’ve finished deploying and checking out our React application, now we can clean up the cluster so it won’t waste any resources:
kubectl delete service,deployment hello
Result:
service "hello" deleted
deployment.extensions "hello" deleted
TL;DR
- React is a Javascript web framework used to develop single-page applications.
- Kubernetes is an open-source platform for orchestration of containerized applications.
- Kubernetes gives us the flexibility to build and deploy our application(s), without needing to rebuild our container images.
- For setting Kubernetes on our local machine we’ll enable Kubernetes from Docker Desktop application.
- Kubernetes can handle huge traffic with replicas of application - pods.
- Kubernetes cluster has a set of multiple machines used for running applications.
- By using Kubernetes, we can solve problems easily and efficiently - saving DevOps a lot of effort.
- For building a Docker container, we’ve made a Dockerfile in the root of the project.
- We also register the image to docker hub to easily pull from anywhere.
- Lastly, we create deployment and service Kubernetes objects to deploy our application to the cluster and expose the service to serve traffic.