Deploy a NodeJS app with Nginx on AWS EC2

Abdulrahman Mohammed
8 min readSep 6, 2020

--

Cloud computing is reshaping the way we build, maintain, collaborate, and deploy modern software programs. Cloud providers are regularly launching new services to cater to the needs of businesses and individuals who operate and provide internet-based solutions.

In this article, we will deploy a NodeJS app on AWS Elastic Compute Cloud (Amazon EC2) which can be reached on a public IP address. NodeJS is an open-source javascript runtime built on Chrome’s V8 JavaScript engine. In this article, you would have:

  • Launched an EC2 instance on AWS free tier
  • SSH into the instance securely
  • Installed Nginx on EC2
  • Installed Nodejs on the instance
  • Deployed your app on the instance
  • And used PM2 to keep your Node app running after the terminal has been closed

Amazon Elastic Compute Cloud (EC2)

Amazon EC2 logo
Amazon EC2 logo

Amazon launched Amazon Web Services(AWS) in 2006 with EC2 as the first public cloud service offering server instances on-demand by leveraging the power of virtualisation. Amazon logically divided the servers in their own data centre and added a software layer over it to create smaller logical servers which they called instances. An EC2 instance on AWS is now offered to the public as virtual machines on the web with configurable size, memory and networking which is available on-demand and billed per seconds. Erstwhile, any business or individual who needs a server has to purchase a physical server and maintain it on-premise, even if they only needed it for a few days in a month or even a year. Applications could also be deployed without having to host hardware or worry about scaling up or down as the need require. In this article, you’ll launch your own Amazon EC2 instance for free.

Traditional architecture has one hardware,one OS, and one application while virtual architecture has one hardware, many OS.
https://www.itfuel.com/blog/9/virtualisation-in-laymans-terms-for-the-smaller-organisation/

NGINX Engine

Nginx is a web server that can also be used as a reverse proxy, load balancer, and HTTP cache. The software was created by Igor Sysoev and publicly released in 2004 as a free and open-source software. A large fraction of web servers use NGINX, often as a load balancer.

Launch an EC2 instance

AWS offers a free tier for some services including t2.micro and t3.micro (dependent on region) machine types with Linux or Windows. Create an account on AWS you can run this instance free for 750 hours every month for a year.

After you have created an account navigate to the EC2 instances page and click the Launch Instances button. Follow these steps to configure your instance:

AWS EC2 Instances dashboard
  • Select an Amazon machine image(AMI). An AMI is a template that contains the software configuration (operating system, application server, and applications) required to launch your instance. Scroll down and select Ubuntu Server 18.04 LTS
  • On the Choose an instance type. Select T2 Micro which is free tier eligible.
  • Click on Next: Configure Instance Details, accept the defaults
  • Click on Next: Add Storage, accept the defaults too
  • Click on Next: Add Tags, add any tags that will help you identify your instance in key/value pairs.
  • Click on Next: Configure Security Groups. There is a default rule there that allows you to SSH into the instance on port 22. Add another rule that allows all IP addresses to access the instance over the internet on port 80. This rule will be a Custom TCP rule, TCP protocol on port 80, source should be set to Anywhere or 0.0.0.0/0. Add a third rule, also Custom TCP rule with the port set to 3000. This rule will allow us to check that our app is running before we set up NginX.
  • Click Review and Launch. The review screen will show all your configurations, check again and click Launch
  • You will be prompted to create a key-pair. A key pair consists of a public key that AWS stores, and a private key that you store. Together, they allow you to connect to your instance securely. For our instance here, we will need the private key file to SSH into our instance securely. In the drop-down menu select Create new key pair. Give the private key any name, I will name mine PK_7.
  • Click on Download Key Pair, note where the file is downloaded and do not delete it. Without this file, you cannot access your instance.
  • Click on Launch Instances and your instance will launch after some minutes.
  • Click on View instances to see your instance in the EC2 instance dashboard.
Instance dashboard showing Instance details

You now have a running EC2 instance congratulations!

SSH into the Instance

The next line of action is to SSH into your instance so you can deploy your application. In the AWS console EC2 instance dashboard, click on the blue checkbox before your instance and then click on the Actions drop-down menu in the top right area of the page. Select on Connect, this will show you instructions on how to SSH into your instance in the SSH Client pane. Mac and Linux users can just run the command:

ssh -i KP_node1.pem ubuntu@55.180.16.47

If you are asked “Are you sure you want to continue connecting (yes/no/[fingerprint])?” type “yes” and hit the Enter key.

This command must be run from the terminal directory where the private key is located. If you used a different name for your private key, you must use the file name you downloaded. The IP address is the public IPv4 address of your instance which you can copy from the instance dashboard.

Windows users can use PuTTY to convert the private key file from pem extension to ppk then connect to the instance. I prefer to use Git Bash instead. Git bash gives you a bash terminal in windows, this will allow you SSH into your instance using the command above.

SSH and updating packages

Install Nginx

Update the packages on the instance by running:

sudo apt update

Install Nginx:

sudo apt install -y nginx
Installing NginX

After this runs successfully, Nginx is now installed on the instance. If you visit the instance public IPv4 address or public IPv4 DNS, which you can find on the Instances dashboard in the AWS console, you will see the Nginx default welcome page.

Install NodeJS and Deploy your Application

Then install the latest version of NodeJS by running the following commands:

curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -sudo apt install -y nodejs
Installing NodeJS

Confirm NodeJS is installed by checking the version of NodeJs installed:

node -v

I installed v14.10.0.

Next install git:

sudo apt install git

Git is a free and open-source distributed version control system. We will clone a git repository containing a simple node app from Github, modify it and deploy. Git should already be installed on the instance.

Confirm git has been installed by invoking the in-built git help command:

git --help

Clone the Node app files from my repo by running

git clone https://github.com/duoarc/node-app.git

Navigate to the repository:

cd node-app

Then install Node dependencies which will create the node-modules folder:

npm install

Your application can now be deployed live when you run:

sudo node index.js

A message on the screen will say “Example app listening on port 3000!”.

If you visit your instance public IPv4 address (example: 55.180.16.47) or public IPv4 DNS (example: ec2–52–86–220–88.compute-1.amazonaws.com) you will get the message

Welcome to Abdulrahman’s first Node app! Keep things Jiggy ;-)

You can edit your index.js file to modify the message and replace Abdulrahman with your name.

Keep App running using PM2

The app will be running as the message is displayed on the terminal. You will not be able to do anything else though in this state. Use Ctrl+C to kill the application. If you try to reach your app from the browser now, you’ll set a site not available message.

We will install PM2 (Production manager 2) to keep live our app so it can run in the background. Run the following command:

sudo npm install pm2 -g
Installing PM2 globally

PM2 will be installed on the server globally (because of the -g flag). Run your app using PM2:

sudo pm2 start index.js

This adds your application to the PM2 process list and PM2 will restart the application if it is killed or crashes.

Running the application with PM2

Set-up a Reverse Proxy Server Using NginX

At this time your node application is live on port 3000 but the NginX welcome page is on port 80, which is the default HTTP port your browser will direct you to when your instance DNS or IP address. We will set up NginX to deliver your application behind a reverse proxy. A reverse proxy is located between your application and the clients accessing it. This prevents anyone from the internet from gaining access into your application. Other than security, the reverse proxy can also be configured to provide SSL termination, Load Balancing, caching and authentication for multiple applications but these are beyond the scope of this article.

NginX files are located in the /etc/nginx/ directory. We will set up our configuration by opening the default file in the sites-available folder:

sudo nano /etc/nginx/sites-available/default

Next, we will replace the location block within the server block in the default file with the following code, replacing <ip-address> with the public ipv4 IP address or DNS address of your instance:

server {
...
location / {
proxy_pass http://<ip-address>:3000;
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;
}
...
}

This will direct requests coming into the IP address or DNS on port 3000 to NginX, which is already serving the IP address on the HTTP port.

Check for errors in the configuration by testing with:

sudo nginx -t

Restart Nginx:

sudo systemctl restart nginx

Your application should be running and accessible via NginX proxy when you enter your instance public DNS name into a web browser.

NginX /sites-available/default

Conclusion

Congratulations, you have now successfully deployed a NodeJS application on Amazon EC2 and kept it running after you close the terminal. Then, you configured a reverse proxy to serve this static page using NginX webserver.

--

--