How to deploy a react app on an Amazon aws ec2 instance and serve it with nginx
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 ๐