Integrate and run a Node and React application to AWS EC2 instance

In this blog post we will learn how to integrate a Node.js and a React app to AWS EC2 instance via NGINX server.

First we need to have an AWS account at least a free tier account.

Then navigate to EC2 Instance dashboard and click Launch Instance button.

This will navigate you to a new page where you need to specify configurations like Operating System, AMI, Security Group etc. Each thing has a great importance when creating a real world app.

Put an appropriate name in the name field section. Most of the time I prefer to use ubuntu as Operating System. So select Ubuntu and chose a basic instance type t2.micro which is free to use. Then create a Key-pair.

For Network Settings you can choose Create Security Group or Select Existing Security Group. If you select Create Security Group make sure to check,

  • Allow SSH traffic from – anywhere. (allowing anywhere is a huge security risk for real world app, don’t do that when you create a production ready app use a known IP)
  • Allow HTTPS traffic from internet.
  • Allow HTTP traffic from internet.

Click Launch Instance button. You will see a new instance created. You may need to wait for some time in order to change “instance state” as running.

Let’s connect to that instance. There are four ways to connect an instance,

  • EC2 Instance Connect.
  • Session Manager.
  • SSH Client.
  • EC2 Serial Console.

We will go with the SSH Client. Copy your SSH command, which will be like below,

ssh -i "my-test-server.pem" ubuntu@ec2-18-298-131-222.compute-1.amazonaws.com

Copy that and open your terminal and navigate to that directory where the .pem key lives and paste it.

You may see a permission required message like,

Load key "my-test-server.pem": bad permissions
root@ec2-18-298-131-222.compute-1.amazonaws.com: Permission denied (publickey).

To give permission to my-test-server.pem file,

chmod 400 my-test-server.pem

After that you will be successfully enter, inside of the instance. The initial path is /home/ubuntu.

Let’s install Node, NPM & Nginx using sudo apt command,

sudo apt install nginx nodejs npm

This will install these three things. You can check it by node -v command.

For NGINX type,

sudo service nginx start
sudo service nginx status

You will see a status active.

After a few time nginx server will be ready and if you go to instance’s Public IPv4 DNS you will see (use http for that),

This means we are successfully serving via nginx. Now let’s install PM2 package globally, which is a process manager for Node.js, in order to keep our application alive forever,

sudo npm i -g pm2

Let’s go back to our initial folder /home/ubuntu. Inside that create two folder called server and client. We need to put our server-side api to server folder and client-side code inside client folder.

Navigate to server folder and run,

pm2 start npm --name “<app_name>” -- run start

here ‘app.js’ is our entry file and then navigate to client folder and run npm run build and then,

pm2 start npm --name “<app_name>” -- run start

Type pm2 list to list down all the applications running under PM2.

Now let’s configure NGINX, which is a Reverse Proxy which routes our traffic to dedicated server. Navigate to nginx/sites-enabled and edit default file (sudo nano default),

server {
  listen 80 default_server;
  listen [::]:80 default_server;
  server_name  localhost;

  # Load configuration files for the default server block.
  include /etc/nginx/default.d/*.conf;

  location / {
    proxy_pass http://localhost:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }

  location /api/ {
    proxy_pass http://localhost:4000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
}

Then type sudo systemctl restart nginx to restart nginx. Go to IpV4 DNS you will see everything is working.

Leave a Comment

Your email address will not be published. Required fields are marked *