# AWS — Deploying React App With NGINX on EKS

<div class="ef eg eh ei ej l" id="bkmrk-a-step-by-step-guide"><div class="ab cl"><div class="dk bf dl dm dn do"><article class="meteredContent"><div class="l"><div class="l"><section>## A step by step guide with an example project

<div><div><div class="hg hh hi hj hk"><div class="">  
</div><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er jc"><picture>![](https://miro.medium.com/max/700/1*GJIEdyhKuy-ruBJnBUgE-g.png)</picture></div></div></figure></div></div></div>AWS provides more than 100 services and it’s very important to know which service you should select for your needs. Amazon Elastic Kubernetes Service (Amazon EKS) is a managed service that makes it easy for you to run Kubernetes on AWS without needing to stand up or maintain your own Kubernetes control plane. Kubernetes is an open-source system for automating the deployment, scaling, and management of containerized applications.

In this post, we are going to deploy the React application with an NGINX web server. First, we dockerize our app and push that image to Amazon ECR and run that app on Amazon EKS.

<div><div><div class="hg hh hi hj hk">- ***Example Project***
- ***Prerequisites***
- ***Dockerize the Project***
- ***Pushing Docker Image To ECR***
- ***Create a Cluster and Worker Nodes***
- ***Configure kubectl to use Cluster***
- ***Deploy Kubernetes Objects On AWS EKS Cluster***
- ***Summary***
- ***Conclusion***

</div></div></div># Example Project

This is a simple project which demonstrates developing and running a React application with NGINX. We have a simple app in which we can add users, count, and display them at the side, and retrieve them whenever you want.

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er uv"><picture>![](https://miro.medium.com/max/700/1*bJMLwcd_90jg4D0ep7YagA.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**Example Project**</figcaption></figure></div></div></div>If you want to practice your own here is a Github link to this project. You can clone it and run it on your machine as well.

```
// clone the project<br></br>git clone <a class="ae qx" href="https://github.com/bbachi/react-nginx-example.git" rel="noopener ugc nofollow" target="_blank">https://github.com/bbachi/react-nginx-example.git</a>// install React dependencies and start<br></br>cd my-app<br></br>npm install<br></br>npm start
```

<div><div><div class="hg hh hi hj hk">  
</div><div class="ab cl vj vk gu vl" role="separator">  
</div><div class="hg hh hi hj hk">  
</div></div></div># Prerequisites

<div><div><div class="hg hh hi hj hk">- If you are new to React please go through the below link on how to develop and build the React project with the NGINX web server.

</div></div></div>> [How To Serve React Application With NGINX and Docker](https://medium.com/bb-tutorials-and-thoughts/how-to-serve-react-application-with-nginx-and-docker-9c51ac2c50ba)

The other prerequisites to this post are Docker essentials and Kubernests essentials. We are not going to discuss the basics such as what is a container or what is Kubernetes, rather, we will see how to build a Kubernetes cluster on AWS EKS. Below are the prerequisites you should know before going through this article

## Docker Essentials

You need to understand Docker concepts such as creating images, container management, etc. Below are some of the links that you can understand about Docker if you are new.

<div><div><div class="hg hh hi hj hk">- [Docker Docs](https://docs.docker.com/)
- [Docker — A Beginner’s guide to Dockerfile with a sample project](https://medium.com/bb-tutorials-and-thoughts/docker-a-beginners-guide-to-dockerfile-with-a-sample-project-6c1ac1f17490)
- [Docker — Image creation and Management](https://medium.com/bb-tutorials-and-thoughts/docker-image-creation-and-management-9d91e4c277b1)
- [Docker — Container Management With Examples](https://medium.com/bb-tutorials-and-thoughts/docker-container-management-with-examples-c280906158a8)
- [Understanding Docker Volumes with an example](https://medium.com/bb-tutorials-and-thoughts/understanding-docker-volumes-with-an-example-d898cb5e40d7)

</div></div></div>## Kubernetes Essentials

You need to understand Kubernetes’ essentials as well along with Docker essentials. Here are some of the docs to help you understand the concepts of Kubernetes.

<div><div><div class="hg hh hi hj hk">- [Kubernetes Docs](https://kubernetes.io/docs/concepts/)
- [How to Get Started with Kubernetes](https://medium.com/bb-tutorials-and-thoughts/how-to-get-started-with-kubernetes-e06ea82d23b)
- [Some Example Projects](https://medium.com/bb-tutorials-and-thoughts/docker/home)

</div></div></div>## AWS account

<div><div><div><div class="hg hh hi hj hk">- AWS account setup: AWS offers a free tier for one year [here is the link to set it up.](https://portal.aws.amazon.com/billing/signup?redirect_url=https%3A%2F%2Faws.amazon.com%2Fregistration-confirmation#/start)
- Once you set it up you have a root account. It’s not a best practice to use your root account to do any tasks instead you should create an IAM group that has permissions for administrator access and add a user to it and log in with that user.
- [Install AWS CLI](https://aws.amazon.com/cli/)
- Configure AWS CLI for the user you just created above. You should use this command `aws configure` and it will ask for access key id and secret key.

<figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er wv"><picture>![](https://miro.medium.com/max/700/0*0UGbycfeM1_I_88I.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**log in with user credentials**</figcaption></figure>- You have to install Docker for Desktop (whatever your OS is). [Please follow this link ](https://docs.docker.com/install/)to install Docker on your laptop. Once installed you can check the Docker info or version with the following commands.

</div></div></div></div>```
docker info<br></br>docker --version
```

<div><div><div class="hg hh hi hj hk">- The Kubernetes command-line tool, [kubectl](https://kubernetes.io/docs/reference/kubectl/kubectl/), allows you to run commands against Kubernetes clusters. [Install it from here.](https://kubernetes.io/docs/tasks/tools/install-kubectl/)

</div><div class="ab cl vj vk gu vl" role="separator">  
</div><div class="hg hh hi hj hk">  
</div></div></div># Dockerize the Project

AWS EKS is a managed service that makes it easy for you to run Kubernetes on AWS. The first thing you need to do is to dockerize your project.

Here is the Dockerfile and it is using multi-stage builds to reduce the image size and surface attacks.

> FROM node:10 AS ui-build  
> WORKDIR /usr/src/app  
> COPY my-app/ ./my-app/  
> RUN cd my-app &amp;&amp; npm install &amp;&amp; npm run build
> 
>   
> FROM nginx:alpine
> 
> \#!/bin/sh
> 
> COPY ./.nginx/nginx.conf /etc/nginx/nginx.conf
> 
> \## Remove default nginx index page  
> RUN rm -rf /usr/share/nginx/html/\*
> 
> \# Copy from the stahg 1  
> COPY --from=ui-build /usr/src/app/my-app/build/ /usr/share/nginx/html
> 
> EXPOSE 4200 80
> 
> ENTRYPOINT \["nginx", "-g", "daemon off;"\]

<div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh"><div class="bz dx l di"><div class="afj pa l">**Dockerfile**</div></div></figure></div></div>Here are the commands to build the image and run it on the Docker engine on your local machine. [If you are new to Docker and check this detailed post on this topic.](https://medium.com/bb-tutorials-and-thoughts/how-to-serve-react-application-with-nginx-and-docker-9c51ac2c50ba)

```
// build the image<br></br>docker build -t react-nginx-ui .// run the image<br></br>docker run -d --name react-nginx-webapp -p 80:80 react-nginx-ui// list the image you just built<br></br>docker images// list the container<br></br>docker ps
```

<div><div><div class="hg hh hi hj hk">  
</div><div class="hg hh hi hj hk"><span style="color: rgb(34, 34, 34); font-size: 3.425em; font-weight: 400;">Pushing Docker Image To ECR</span>  
</div></div></div>Amazon Elastic Container Registry (ECR) is a fully-managed [Docker](https://aws.amazon.com/docker/) container registry that makes it easy for developers to store, manage, and deploy Docker container images. Amazon ECR is integrated with [Amazon Elastic Container Service (ECS)](https://aws.amazon.com/ecs/), simplifying your development to production workflow.

Amazon ECS works with any Docker registry such as Docker Hub, etc. But, in this post, we see how we can use Amazon ECR to store our Docker images. Once you set up the Amazon account and create an IAM user with Administrator access the first thing you need to create a Docker repository.

You can create your first repository either by AWS console or AWS CLI

## AWS console

Creating a repository with AWS console is straightforward and all you need to give a name.

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er ww"><picture>![](https://miro.medium.com/max/700/1*k2QhbRtUmJU31MkwnOiyWw.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**creating repository**</figcaption></figure><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er wx"><picture>![](https://miro.medium.com/max/700/1*4PLDc5xEE6VPezynMh7Jaw.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**repository**</figcaption></figure></div></div></div>## AWS CLI

The first thing you need to do is authenticate to your default registry. Here is the command to authenticate to your default registry. You need to make sure you are putting the correct regions and account id in the command.

```
aws ecr get-login-password <strong class="va ho">--region us-east-1</strong> | docker login --username AWS --password-stdin <strong class="va ho">aws_account_id</strong>.dkr.ecr.<strong class="va ho">us-east-1</strong>.amazonaws.com
```

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er wy"><picture>![](https://miro.medium.com/max/700/1*GQsxkIV46hhZjId27uiHiQ.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**Authenticating to ECR**</figcaption></figure></div></div></div>It’s time to create a repository with the following command

```
<strong class="va ho">aws ecr create-repository \     <br></br>     --repository-name frontend/web-app \     <br></br>     --image-scanning-configuration scanOnPush=</strong><em class="tx">true</em><strong class="va ho"> \<br></br>     --image-tag-mutability IMMUTABLE \    <br></br>     --region </strong><em class="tx">us-east-2</em>
```

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er wz"><picture>![](https://miro.medium.com/max/700/1*XAKxNO32XLxFqTI4D2rmbw.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**Creating repository**</figcaption></figure></div></div></div>You will have the same result as well.

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er xa"><picture>![](https://miro.medium.com/max/700/1*EnjMQn5p-tO9OJuFMAtSkA.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**Repository**</figcaption></figure></div></div></div>## Tagging your local Docker image and Pushing

You have created a Docker image on your local machine earlier. It’s time to tag that image with this repository URI in the above image.

```
docker tag react-nginx-ui:latest 864227929192.dkr.ecr.us-east-2.amazonaws.com/frontend/web-app:v1
```

Once you tag the image and it’s time to push the Docker image into your repository.

```
// list the images<br></br>docker images// push the image<br></br>docker push 864227929192.dkr.ecr.us-east-2.amazonaws.com/frontend/web-app:v1
```

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er xb"><picture>![](https://miro.medium.com/max/700/1*bb7bIP2GTMGjEQCaioDXPg.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**pushing Docker image**</figcaption></figure><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er xc"><picture>![](https://miro.medium.com/max/700/1*5keAUXHQlS7zHA1ds_ux6A.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**Docker image with tag v1**</figcaption></figure></div><div class="ab cl vj vk gu vl" role="separator">  
</div><div class="hg hh hi hj hk">  
</div></div></div># Create a Cluster and Worker Nodes

Getting started with AWS EKS is easy all you need to do the following steps

<div><div><div class="hg hh hi hj hk">- We need to create an AWS EKS cluster with AWS console, SDK, or AWS CLI.
- Create a worker node group that registers with EKS Cluster
- When your cluster is ready, you can configure **kubectl** to communicate with your cluster.
- Deploy and manage your applications on the cluster

</div></div></div>## Cluster Creation

Let’s create a cluster by [following this guide here](https://docs.aws.amazon.com/eks/latest/userguide/create-cluster.html). Make sure you created a role for the EKS to allow Amazon EKS and the Kubernetes control plane to manage AWS resources on your behalf. I created a role called **eks\_cluster\_role.** [**Here is a link to create a cluster role.**](https://docs.aws.amazon.com/eks/latest/userguide/service_IAM_role.html#create-service-role)

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er xd"><picture>![](https://miro.medium.com/max/700/1*vMAdsWmlRv-MWgKhyRNAxg.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**eks\_cluster\_role**</figcaption></figure></div></div></div>Let’s create a cluster by giving the below information.

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er xe"><picture>![](https://miro.medium.com/max/700/1*07MFFsDAm7rRlii1gtYOig.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**Creating Cluster**</figcaption></figure></div></div></div>It takes some time for the cluster to get created and it should be in the active state once it is created.

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er xf"><picture>![](https://miro.medium.com/max/700/1*BLaV_lmCh7iVcVAmmbPvEA.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**Cluster Created**</figcaption></figure></div></div></div>## Create Worker Nodes

It’s time to create nodes and before you do that we have to create this role called NodeInstanceRole. [Follow this guide to create one.](https://docs.aws.amazon.com/eks/latest/userguide/worker_node_IAM_role.html)

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er xg"><picture>![](https://miro.medium.com/max/700/1*qHPRLK6ZFXO1fa1jdP-W7g.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**NodeInstanceRole**</figcaption></figure></div></div></div>[Follow this guide to create a node group after the role is created.](https://docs.aws.amazon.com/eks/latest/userguide/create-managed-node-group.html)

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er xh"><picture>![](https://miro.medium.com/max/700/1*hLWYrJCSTHKsGgGAfnc0ew.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**Node Group is active**</figcaption></figure></div><div class="ab cl vj vk gu vl" role="separator">  
</div><div class="hg hh hi hj hk">  
</div></div></div># Configure kubectl to use Cluster

<div><div><div><div class="hg hh hi hj hk">- We need to install kubectl on our machine, [follow this guide to install depending on your OS.](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
- The next thing we need to do is to install an aws-iam-authenticator. [Follow this guide.](https://docs.aws.amazon.com/eks/latest/userguide/install-aws-iam-authenticator.html) We need this to authenticate the cluster and it uses the same user as AWS CLI is authenticated with.
- Use the AWS CLI **update-kubeconfig** command to create or update your kubeconfig for your cluster. Here region-code is **us-east-2** and cluster\_name is **frontend\_clutser**

</div></div></div></div>```
aws eks --region <strong class="va ho"><em class="tx">region-code</em></strong> update-kubeconfig --name <strong class="va ho"><em class="tx">cluster_name</em></strong>
```

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er xi"><picture>![](https://miro.medium.com/max/700/1*1HkxHLDn_qyYXCXm5gqtXQ.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**connected to the cluster**</figcaption></figure></div></div></div>You can check with these commands.

```
// get the service<br></br>kubectl get nodes// get the current context<br></br>kubectl config current-context
```

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er xj"><picture>![](https://miro.medium.com/max/700/1*9BB2Rq3jQWMi0bvtT7aEAQ.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**connected to cluster**</figcaption></figure></div><div class="ab cl vj vk gu vl" role="separator">  
</div><div class="hg hh hi hj hk">  
</div></div></div># Deploy Kubernetes Objects On AWS EKS Cluster

Now we have configured kubectl to use AWS EKS from our own machine. Let’s create deployment and service objects and use the image from the AWS ECR. Here is the manifest file which contains these objects.

> apiVersion: apps/v1  
> kind: Deployment  
> metadata:  
>  creationTimestamp: null  
>  labels:  
>  app: nginx-webapp  
>  name: nginx-webapp  
> spec:  
>  replicas: 5  
>  selector:  
>  matchLabels:  
>  app: nginx-webapp  
>  strategy: {}  
>  template:  
>  metadata:  
>  creationTimestamp: null  
>  labels:  
>  app: nginx-webapp  
>  spec:  
>  containers:  
> \- image: 864227929192.dkr.ecr.us-east-2.amazonaws.com/frontend/web-app:v1  
>  name: webapp  
>  imagePullPolicy: Always  
>  resources: {}  
>  ports:  
> \- containerPort: 80   
> status: {}
> 
> \---
> 
> apiVersion: v1  
> kind: Service  
> metadata:  
>  name: nginx-webapp  
>  labels:  
>  run: nginx-webapp  
> spec:  
>  ports:  
> \- port: 80  
>  protocol: TCP  
>  selector:  
>  app: nginx-webapp  
>  type: LoadBalancer

**manifest.yml**

</section></div><div class="l"><section>If you cloned the above example project and you are at the root folder just use this command to create objects `kubectl create -f manifest.yml`

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er xk"><picture>![](https://miro.medium.com/max/700/1*xaBo1thbhM4lGFmjkTiqWA.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**kubectl create -f manifest.yml**</figcaption></figure></div></div></div>You can use the following commands to verify all the objects are in the desired state.

```
// list the deployment<br></br>kubectl get deploy// list the pods<br></br>kubectl get po// list the service<br></br>kubectl get svc
```

<div><div><div class="hg hh hi hj hk"><figure class="jd je jf jg fc jh eq er paragraph-image"><div class="ji jj di jk bf jl" role="button" tabindex="0"><div class="eq er xl"><picture>![](https://miro.medium.com/max/700/1*qMF_By2CFYtdTjBz6Ei1tQ.png)</picture></div></div><figcaption class="uw mz es eq er ux uy bd b be z dw" data-selectable-paragraph="">**all objects are deployed**</figcaption></figure></div><div class="ab cl vj vk gu vl" role="separator">  
</div><div class="hg hh hi hj hk">  
</div></div></div># Summary

<div><div><div class="hg hh hi hj hk">- Amazon Elastic Kubernetes Service (Amazon EKS) is a managed service that makes it easy for you to run Kubernetes on AWS without needing to stand up or maintain your own Kubernetes control plane.
- You need to create an AWS Account as a prerequisite.
- It’s not a best practice to use your root account to do any tasks instead you should create an IAM group that has permissions for administrator access and add a user to it and log in with that user.
- You should use this command `aws configure` with access key and secret key.
- Amazon EKS is a managed service that makes it easy for you to run Kubernetes on AWS.
- Amazon Elastic Container Registry (ECR) is a fully-managed [Docker](https://aws.amazon.com/docker/) container registry that makes it easy for developers to store, manage, and deploy Docker container images.
- Amazon ECR is integrated with [Amazon Elastic Container Service (ECS)](https://aws.amazon.com/ecs/), simplifying your development to production workflow.
- Amazon ECS works with any Docker registry such as Docker Hub, etc.
- You have to follow these steps to run apps on the Kubernetes cluster: we need to create an AWS EKS cluster with AWS console, SDK, or AWS CLI. Create a worker node group that registers with EKS Cluster, when your cluster is ready, you can configure **kubectl** to communicate with your cluster, Deploy and manage your applications on the cluster

</div><div class="ab cl vj vk gu vl" role="separator">  
</div><div class="hg hh hi hj hk"><span style="color: rgb(34, 34, 34); font-size: 3.425em; font-weight: 400;">Conclusion</span>  
</div></div></div>We have deployed a simple React application with an NGINX web server on AWS EKS Cluster. In future posts, we will see how we can add a load balancer and how we can route requests to the Kubernetes Cluster.

</section></div></div></article></div></div></div>