How to deploy a react app on an Amazon aws ec2 instance and serve it with nginx

ยท

6 min read

So the goal of this tutorial is to describe how to get a react app from your laptop/pc onto the internet by putting it in an Amazon aws ec2 container and using nginx to serve the app. The tutorial assumes you already have an aws account and can log into it, if you do not its fairly easy to create, you will however have to link a credit card to be eligible for the free tier, Amazon wont charge anything unless you go over the limits of the free tier, which are enough for this tutorial.

Step one: log into aws and configure an ec2 virtual machine

After creating an account select ec2 from the options presented, if ec2 is not visible type it in the search bar and click on the EC2 option.

After clicking on EC2, click on the launch instance button to enter the configuration panel where you can set up the EC2 virtual machine.

Launch instance takes you to a configuration panel where you can set things such as storage size, operating system, connection options among other settings. For this tutorial I went with ubuntu.

In the configuration panel, create a key pair that will let you ssh into the virtual machine. Clicking the create key pair button will download a .pem file onto your computer.

After creating the key pair, edit the network settings. Select the options to allow ssh traffic and also allow HTTP and HTTPS traffic from the internet, this will let anyone visit your website over the internet. For the ssh option you can limit it to your IP to make sure no one else has access to your virtual machine.

For the other options, you can leave them as default, click the launch instance button to create the EC2 instance.

After the instance has been created connect to it and select the SSH client tab which contains the ssh commands you need to log into the virtual machine

Step two: log into the virtual machine and install the necessary dependencies

Remember the .pem that was downloaded on your laptop when you were configuring the instance? Navigate to where it was downloaded and change its permission using chmod to enable ssh, in my case the key was named shasa-main-thinkpad-aws-key.pem.

chmod 400 shasa-main-thinkpad-aws-key.pem

After running the chmod command the next step is to ssh into the virtual machine, you can copy the command displayed on the connect instructions panel on aws.

ssh -i "<your_key_pair_name>.pem" ubuntu@<your ec2 details>.compute.amazonaws.com

After this you will be successfully logged into the terminal of your virtual machine and can begin installing the necessary packages to run the react app, first step is nodejs. Type out the following commands to install node

sudo apt update
sudo apt upgrade
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs

Step three: moving the files from localhost onto the virtual machine

Now that the virtual machine is up and running and has node installed we can move the react source code onto the virtual machine. On your terminal cd into the folder/directory with the react code and then use the rsync command.

rsync -avz --exclude 'node_modules' --exclude '.git' --exclude '.env' \
-e "ssh -i ~/Downloads/shasa-main-thinkpad-aws-key.pem" \
. ubuntu@<your virtual machine ip>.compute.amazonaws.com:~/app

Here we are telling rsync to exclude the node_modules and git folder and also ignore any .env files. The source code will be placed in the ~/app folder in your vm. You can use the ls command to verify that an ~/app folder has been created and contains the react source code.

After moving the react source code onto the virtual machine and placing them in the ~/app folder, cd into that folder inside the ec2 machine and install node modules then use the build command to generate a production build with the static files that we can then serve using nginx. If the app was scaffolded using create-react-app then the build command will be npm run build

npm install
npm run build

The build command will create a build folder, in my case these were the files after generating the build

Step Four: installing nginx and serving the website

Now we install nginx which we will configure to serve the index.html from the build folder and make it accessible at the server's IP address listening on port 80

sudo apt install nginx

After installing nginx, create a new folder /var/www/vhosts/frontend/ and copy the build folder into /var/www/vhosts/frontend/ we will then point nginx to the new build location

sudo mkdir -p /var/www/vhosts/frontend/ #creating the folder
sudo cp -R ./app/build/ /var/www/vhosts/frontend/ #copying the build folder into the new location

Configure nginx by navigating to /etc/nginx/sites-available/ , deleting the default config file and creating a new one with the name you want to give to your app, in my case it was weatherapp

cd /etc/nginx/sites-available/
sudo rm default
touch weatherapp # this is the name of the react website containing nginx config

Use nano to modify weatherapp with the nginx config details, typing nano weatherapp will open up an editing panel where you can enter details, replace weatherapp with whatever name you gave to your app.

Use the following nginx config details to modify the file weatherapp The details will have nginx listen on port 80 and serve the index.html inside the folder /var/www/vhosts/frontend/build whenever a request is made to the virtual machine's IP address.

server {
        listen 80 default_server;
        server_name _;

        location /{
                autoindex on;
                root /var/www/vhosts/frontend/build; #this is the path to the index file
                try_files $uri /index.html;
        }
}

save the config then create a symbolic link to the /etc/nginx/sites-enabled folder using this command

sudo ln -s /etc/nginx/sites-available/weatherapp /etc/nginx/sites-enabled/weatherapp

Now test that the config is correct using the command sudo nginx -t if everything is ok you will see an output similar to the following.

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If your terminal shows something else you could have a typo in the weatherapp config, or a missing ; at the end of a line.

restart nginx using the command sudo systemctl reload nginx and the react app should now be live at the virtual machine's IP address. You can find the IP address of your ec2 instance by logging into the aws console, selecting ec2 and viewing the details of the running instance in the networking tab, it should be labeled Public IPv4 address

There are further steps for a proper website such as adding ssl certificate and a domain name but for now your react app has graduated from localhost and is live on the internet ๐ŸŽ‰