Easy Deployment of Nodejs Applications on EC2 with PM2 and NGINX
Deploying Node.js applications can be a daunting task, especially when aiming for a robust and scalable production environment. However, with the right tools and a clear process, it becomes much more manageable. In this guide, I will walk you through the easy deployment of Node.js applications on Amazon EC2 using PM2 and NGINX. By the end of this article, you'll have a solid understanding of how to set up your server, manage your application processes, and configure a reverse proxy to handle incoming traffic efficiently. Let's dive in!
Initializing the Node project
For this walkthrough, I will be deploying a simple Express hello-world application on EC2. Let's start by initialize a simple express app
npm init -y
Add express as a dependency
npm install express
Adding a simple / endpoint that returns a hello world object
const express= require("express");
const app= express();
app.get("/",(req,res)=>{
res.json({ message: "Hello world" });
});
const PORT= 3000;
app.listen(PORT,()=>{
console.log("app is listening on port " + PORT );
});
Start your express application
node index.js
and you see a / endpoint like this
Deploying the app on AWS EC2
Let's bootstrap an EC2 instance
You can directly head over to AWS EC2 create instance page
You can name the ec2 instance according to you, I am naming it demo-nodejs
.
Select any image that suits you best, or you can learn more about these here. I have selected the basic Ubuntu image, as it is widely used and has good support.
Since I am using this instance for this walkthrough, I have selected a free-tier Instance type, you can choose the instance types according to your need, know more about this here
And finally launch the instance, I am going to access this instance from AWS connect, If you want to ssh into the instance you can create a key-pair and do that
Click on connect to access your instance and start setting up your environment.
Now you have access to you ec2 instance from your brower
Setting up the Environment in the instance
Update the package lists by running:
sudo apt-get update && sudo apt-get upgrade
Installing node using the NVM(Node Version Manager)
Reference: How To Install Node.js on Ubuntu 20.04
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
This will install the nvm
script to your user account. To use it, you must first source your .bashrc
file:
source ~/.bashrc
Now let's install node using the nvm
nvm install node
To check if it is installed correctly:
node --version
Starting the server on EC2
You can either upload your code on GitHub and then clone it in Ec2 or use any other viable method to get your code on the instance.
If you are able to see this or whatever log you added in the app.listen()
you are good to go.
Starting the server with pm2
Now we can do a node index.js
and we're good to go, but this approach has its limitations. Running your application this way means it won't automatically restart if it crashes, and it won't start again if the server reboots. This is where PM2 comes in. PM2 is a production process manager for Node.js applications that ensures your application stays online, even in the face of unexpected issues. It provides features like process monitoring, automatic restarts, and load balancing, making it an essential tool for managing Node.js applications in a production environment. Let's explore how to set up and use PM2 to manage our Node.js application on EC2.
So let's install pm2
npm install -g pm2
Now we'll start the express app using pm2
pm2 start index.js
Now we have deployed the app, but it won't be accessible on the internet yet. To make it accessible, let's configure the necessary security groups and open the required ports. This will allow external traffic to reach our application.
Navigate to the Security tab on the Instance page. and click on the Security group which is sg-09f5337d4845d84fb (launch-wizard-1)
here.
Click on Edit inbound rules
Add a new Inbound rue with Type of Custom TCP
and PORT 3000
. To make it accessible add 0.0.0.0/0
from the CIDR block.
Now get the Ip from the home page of your instance
My Instance's Ip is ec2-54-242-52-243.compute-1.amazonaws.com
, Now the app is deployed on port 300, So to access the app navigate to
http://ec2-54-242-52-243.compute-1.amazonaws.com:3000
And voilà! Your application is now accessible on the internet.
But wait the url for the application is https://ec2-54-242-52-243.compute-1.amazonaws.com:3000, prettly ugly to add :3000
in the url. Have you ever seen we go to http://google.com:5173. No! right, So let's fix this next
Configuring Nginx
To make your application accessible without appending the port number to the URL, we will set up NGINX as a reverse proxy. This will allow NGINX to handle incoming traffic on the default HTTP port (80) and forward it to your Node.js application running on port 3000.
Steps to add and Install nginx
Install NGINX
First, install NGINX on your EC2 instance by running the following commands:
sudo apt update sudo apt install nginx
Start and Enable NGINX
Ensure that NGINX is running and set to start on boot:
sudo systemctl start nginx sudo systemctl enable nginx
Configure NGINX as a Reverse Proxy
Open the NGINX configuration file for editing:
sudo vi /etc/nginx/sites-available/default
Replace the contents of the file with the following configuration:
server { listen 80; server_name ec2-54-242-52-243.compute-1.amazonaws.com; location / { proxy_pass http://localhost: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; } }
Make sure to replace
ec2-54-242-52-243.compute-1.amazonaws.com
with your actual domain name or public IP address.Test the NGINX Configuration
Test the NGINX configuration to ensure there are no syntax errors:
sudo nginx -t
If the test is successful, you should see a message indicating that the configuration file is okay.
Restart NGINX
Restart NGINX to apply the new configuration:
sudo systemctl restart nginx
Update Security Group to Allow HTTP Traffic
Ensure that your EC2 instance's security group allows inbound traffic on port 80. Navigate to the Security Groups section in the AWS Management Console, select your instance's security group, and add a rule to allow HTTP traffic on port 80 from any IP address (0.0.0.0/0) and you may remove the 3000 port that's no more needed
Access Your Application
Now, you should be able to access your Node.js application using your domain name or public IP address without appending the port number. For example:
http://your_domain_or_IP
Your application should be accessible, and NGINX will forward the traffic to your Node.js application running on port 3000.
By following this guide, you have successfully deployed a Node.js application on an EC2 instance using PM2 and NGINX. This setup not only ensures that your application remains robust and scalable but also provides a clean and professional URL for your users. With PM2 managing your application processes and NGINX handling incoming traffic, you can focus on developing your application further, knowing that your deployment is in good hands. Happy coding!
Subscribe to my newsletter
Read articles from Pulkit directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Pulkit
Pulkit
Hi there! 👋 I'm Pulkit, a passionate web and app developer specializing in MERN and React Native technologies. With a keen interest in open-source contributions and competitive programming, I love building innovative solutions and sharing my knowledge with the community. Follow along for insights, tutorials, and updates on my coding journey!