Deploying React App Using AWS Elastic Beanstalk

Roy Alingcastre
5 min readNov 11, 2020

--

Photo by NESA by Makers on Unsplash

AWS Elastic Beanstalk simplifies the deployment of web applications on AWS. It caters to different types of applications. In this article I will be using a React application to demonstrate how easy it is to deploy an app on AWS using Beanstalk. I will also ship the application in a Docker container to further simplify the deployment process.

Prerequisites

To perform the steps below, you will need an AWS account to access AWS cloud platform and services. You will also need Node.js and npm installed on your workstation. You can find the instruction for installing these applications on the ReactJS site. You will also need Docker Desktop and AWS CLI installed.

1. Create a React app

First, let us create a single-page app using the create-react-app command as shown below.

>npx create-react-app my-app

We can test the generated app using the following commands. The npm command should automatically open a browser directed to http://localhost:3000, showing the React logo.

>cd my-app
>npm start

2. Dockerize the app

Now let us setup our app to run in a Docker container. Create a file called dockerfile.dev in the my-app folder and paste the following configuration into the file. This Docker configuration is used for creating an image for our local testing.

In the above configuration we are using the alpine version of node, which has a smaller image footprint than the full version.

Create a .dockerignore file with the following content.

Use the following command to build the Docker image.

>docker build -f dockerfile.dev -t my-app:dev .

We can confirm that the image is successfully created using the command below. The command lists the available images which should include, my-app with tag dev.

>docker images

Once we have confirmed that the image is created we can start an instance using the command below.

>docker run -p 3030:3000 my-app:dev

In step 1, we accessed the app through port 3000 (http://localhost:3000), which is using a default port. The port flag option above maps this default port to port 3030 of our localhost. We can then access the app by going to http://localhost:3030 in our browser and Docker will then redirect the request to the container’s port 3000. We should then see the same page as we saw in step 1.

Next, we’ll create dockerfile.prod in the my-app folder with the following configuration for creating the production image of our app. There are two key differences in this configuration: 1) it only includes production-only dependencies and, 2) it uses nginx for app hosting, which is a high-performance web server.

We create a new folder called nginx inside the my-app folder. Create a file called nginx.conf inside the nginx folder that contains the configuration below.

Similar to the above commands, create the production image using the command below.

>docker build -f dockerfile.prod -t my-app:prod .

We then use the command below to create an instance of the image.

>docker run -p 8080:80 my-app:prod

Now we can access the app through http://localhost:8080 in our browser. Note that we have configured nginx to listen to port 80, so here we are mapping port 80 to port 8080 of our localhost.

3. Upload the app to the cloud

We will use AWS Elastic Beanstalk to deploy our application to the cloud. Create a new application through the Elastic Beanstalk console. Let’s give it a name called my-app. Under Platform, select Docker and leave the rest of the settings as default.

A few options are available for deploying Docker images, as discussed in the Elastic Beanstalk documentation. For this demonstration, we will use AWS ECR (Elastic Container Registry) to store our app image and publish it to Beanstalk from there.

We create a new repository through the ECR management console. In the Create repository page, we give our repo name as my-app. We can leave the rest of the options as default. Once the repo is created, we should find it in the repositories list. Select the repo from the list and view the push command. We use these commands to push the Docker image to our repo.

Note: the push commands are specific to your account and repo so the commands provided below will be slightly different for your account.

First, we retrieve an authentication token using the command below. We need AWS CLI installed to complete these steps.

>aws ecr get-login-password — region us-west-2 | docker login — username AWS — password-stdin <accountid>.dkr.ecr.us-west-2.amazonaws.com

We create a new image based on the my-app:prod image with a different tag using the following command.

>docker tag my-app:prod <accountid>.dkr.ecr.us-west-2.amazonaws.com/my-app:latest

We push the new image to the ECR using the following command.

>docker push <accounted>.dkr.ecr.us-west-2.amazonaws.com/my-app:latest

We can verify that the image was successfully pushed by logging into the ECR console and checking that the repo is in the repositories list. Select the repo we created and copy the image URI.

Next, we create a new file called docker-compose.yml inside the my-app folder and paste the following configuration into the file. We need to replace the image configuration in the file with the image URI we copied from the ECR console.

Before Elastic Beanstalk can pull the image from the ECR repositories, we need to give Beanstalk access to it. Beanstalk uses a role called aws-elasticbeanstalk-ec2-role as the instance profile. We need to attach a policy to the role to give it permission to access the repositories. Navigate to the IAM (Identity and Access Management) console and go to the roles list. Search and select aws-elasticbeanstalk-ec2-role from the list. Under the Permissions tab, select attach policies and search for AmazonEC2ContainerRegistryReadOnly and attach the policy.

Go back to the Elastic Beanstalk console and select myapp-env. We should see a dashboard similar to below. We upload the docker-compose.yml file using the Upload and deploy button. Once the deployment process is completed, we can access the app through the link provided below the env name, for example http://myapp-env.eba-hpmabhk.us-west-2.elasticbeanstalk.com, as shown below. Opening the link through a browser should load the same React app page, as we have seen in step 1.

Conclusion

So there you go, we have created a skeleton React app, created a Docker image of it, and shipped it to AWS using the AWS Elastic Beanstalk service. Beanstalk makes the deployment experience seamless by hiding the complexity involved in provisioning an AWS EC2 instance and publishing an application to it.

--

--