Carlos Mucuho A geologist-turned-programmer.

Deploy a React app to Kubernetes using Docker

5 min read 1678

In this tutorial, we will learn how to use Docker, minikube, and kubectl to deploy a React application to Kubernetes. Let’s take a closer look at these tools to learn about why they are the best choice for deploying containerized React applications.

Docker is an open source software containerization platform that allows you to package applications into standardized, isolated units called containers. These containers combine the applications source code with the operating system libraries and dependencies required to run that code in any environment.

Docker allows you to build, test, deploy, and scale applications quickly. Its development speed, scalability, and ecosystem richness are some of the many reasons why we will use it to containerize a React application. Please keep in mind that using Docker to containerize is also known as “dockerizing” in the developer community.

Kubernetes is an open source tool that allows you to automate the deployment, scaling, and management of containerized applications. We are going to use it to deploy and manage our dockerized React app.

Next, minikube is a tool that sets up a local Kubernetes cluster on macOS, Linux, and Windows. We are going to use this tool to run Kubernetes locally instead of using a cloud provider.

Finally, kubectl is the Kubernetes command-line tool that allows us to run commands against Kubernetes clusters. We will use this tool to deploy our dockerized React application, and inspect and manage our local Kubernetes cluster resources.

Prerequisites

In order to follow this tutorial you will need a machine with the following tools installed:

  • Node.js and npm (Node ≥v14.0.0 and npm ≥v5.6)
  • Docker
  • kubectl
  • minikube

Along with the tools mentioned above, you will also need a Docker Hub account.

Creating a React application

In this section, we will create the project directory structure to store our application files. After that, we’ll create a React application with Create React App, test the application, and build it for production.

Creating the project directory structure

Create the project directory and navigate into it like so:



mkdir react-docker-kubernetes
cd react-docker-kubernetes

Create a directory called K8s to store your Kubernetes files, and another named react-docker to store your React application and Docker files:

mkdir K8s 
mkdir react-docker

Creating a React application and building it for production

Run the following command to create a new React application in the react-docker directory, then navigate into it and start the application:

npx create-react-app react-docker

You can manually navigate to your application by navigating to the following URL: http://localhost:3000/

The application should look like this:

When you start running the application with npm start, by default the application will run on port 3000 if there isn’t an application running there already. You can change this behavior by creating a .env file and manually setting the port inside it.

Close the process running your React app, then create a .env and add the following content to it to set the port to 3002:

PORT=3002

Let’s build our application for production with the following command:


More great articles from LogRocket:


npm run build

When the command above finishes executing, the files of our production-ready application will be available in a directory named build.

Dockerizing the React application

In this section, we will create a Docker image of our React application, run and test a container created from the application image, then push it to a Docker Hub account.

Before we can proceed, you need log in to your Docker Hub account.

To do so, run the following command:

docker login

You will be asked to enter your Docker Hub account’s username and password, and if you are successful, you will see the following message:

Login Succeeded

Creating the Docker image

In order to create a Docker image, we have to create two important files: Dockerfile and .dockerignore. A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. A .dockerignore file is a text document that contains a list of files and directories that a user wants to ignore while assembling an image.

In the root directory of your project, enter the following code into Dockerfile:

FROM nginx:stable-alpine

COPY build/ /usr/share/nginx/html 

In the code above, we are pulling the base image for our dockerized application, which contains Nginx running on Alpine Linux. Nginx is an open-source web server that can also be used as a reverse proxy, load balancer, mail proxy, and HTTP cache.

After pulling the base image, you are copying the directory that contains the files of our React application to a directory where Nginx will be able to access them and serve the application.

Now, add the following code to .dockerignore:

npm-debug.log
.dockerignore
**/.git
**/.DS_Store
**/node_modules

In the code above, we declared the files and directories that we wish to exclude from our Docker image.

Now that we have created Dockerfile and .dockerignore, we are ready to build the Docker image of our React application.

Run the following command to build the image:

docker build -t your_docker_username/react-docker .

With the command above, we created the image and set its name to react-docker. Replace your_docker_username with your Docker Hub account’s username.

Now, run the dockerized application with the following:

docker run -d -p 3000:80 your_docker_username/react-docker

The command above starts a Docker container with your image in detached mode, and maps our machine port 3000 to the container port 80 where our Docker container is running.

Open your preferred browser and navigate to http://localhost:3000/, and you should see your React application page.

After testing the application, make sure you stop all containers with the following command:

docker stop $(docker ps -a -q)

Now that you have successfully tested that the container runs, use the following command to push your image to your Docker Hub account:

docker push your_docker_username/react-docker:latest

When the command above finishes executing, anyone with Docker installed will be able to pull your dockerized React application.

Deploying our React app to Kubernetes

In this section, we will start a local Kubernetes cluster, configure the cluster, then deploy our dockerized application to the cluster and scale it.

Starting and configuring a local Kubernetes cluster

To begin, navigate to the K8s directory like so:

cd ../K8s

Start your local Kubernetes cluster with minikube:

minikube start

Then, use kubectl to create a new namespace called react-docker:

kubectl create namespace react-docker

Now, set react-docker as the default context:

kubectl config set-context --current --namespace=react-docker

Deploying the dockerized application to Kubernetes

Create a file called deployment.yaml and add the following code to it:

kind: Deployment
apiVersion: apps/v1
metadata:
  name: react-docker
spec:
  replicas: 2
  selector:
    matchLabels:
      app: react-docker
  template:
    metadata:
      labels:
        app: react-docker
    spec:
      containers:
      - name: react-docker
        image: your_docker_username/react-docker
        ports:
        - containerPort: 80

In the deployment.yaml file above, we set the name of our app deployment to react-docker and the number of pods to 2.

Next, we specified the image that we want to use to build your app as your_docker_username/react-docker. Now, replace your_docker_username with your actual Docker Hub username.

Lastly, we specified that the container is running on port 80.

Deploy the application with the following:

kubectl apply -f deployment.yaml

And monitor the status of the deployment with the following command:

kubectl get deployment -w

After running the command above, you should see an output similar to this:

NAME           READY   UP-TO-DATE   AVAILABLE   AGE
react-docker   0/2     2            0           18s
react-docker   1/2     2            1           23s
react-docker   2/2     2            2           29s

To access your app from outside the cluster, you will need to create a service. This service will be a load balancer.

Create a file load-balancer.yaml file and add the following code to it:

apiVersion: v1
kind: Service
metadata:
  name: load-balancer
  labels:
    app: react-docker
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    nodePort: 31000
  selector:
    app: react-docker

Here, we set the name of the service to load-balancer.

We also specified the service type, made the service accessible on port 80, and set the nodePort to 31000. This nodePort is the port on which we will be able to access the application. Finally, we indicated that this service is for the react-docker app.

Now, we can deploy the service like so:

kubectl apply -f load-balancer.yaml

And we can monitor the status of the service with the following command:

kubectl get services -w

We should get an output similar to the following:

NAME                TYPE     CLUSTER-IP        EXTERNAL-IP     PORT(S)      AGE
load-balancer   LoadBalancer   10.101.114.62   <pending>     80:31000/TCP   50s

The application will be accessible on the following URL:

http://your_minikube_ip:31000

Next, use the following command to get the minikube IP address:

minikube ip

Replace your_minikube_ip with the IP address returned by the minikube ip command.

Navigate to the URL and you will be able to access the dockerized application running on Kubernetes.

Scaling the application

Now, we can scale up our application by increasing the number of pods to ten with the following command:

kubectl scale deployment react-docker --replicas=10

Monitor the status of the deployment like so:

kubectl get deployment -w

You should see that we now have ten pods running the React application:

NAME           READY   UP-TO-DATE   AVAILABLE   AGE
react-docker   5/10    10           5           39m
react-docker   6/10    10           6           40m
react-docker   7/10    10           7           40m
react-docker   8/10    10           8           40m
react-docker   9/10    10           9           40m
react-docker   10/10   10           10          40m

We can also scale down the application by decreasing the number of pods. In the this case, three:

kubectl scale deployment react-docker --replicas=3

We can monitor the status of the deployment exactly as we did before, and you should see that we now have three pods running the application:

NAME           READY   UP-TO-DATE   AVAILABLE   AGE
react-docker   3/3     3            3           41m

Conclusion

In this tutorial, we learned how to create a React application and build it for production. After building the application, we learned how to dockerize and push it to your Docker Hub account. Finally, we learned how to create and configure a local Kubernetes cluster, deploy the dockerized React application to the cluster, and how to scale the application.

For more information on how to dockerize applications and how to deploy them to a Kubernetes cluster make sure you read the Docker and Kubernetes documentation.

Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — .

Carlos Mucuho A geologist-turned-programmer.

Leave a Reply