Step-by-Step Guide to Deploy NodeJS app with PM2 on AWS EC2 instance

Dinesh Rawat
calendar_month
September 30, 2024
timer
6 min
read time

Deploying your Node.js app to the cloud has never been easier. In 2024, AWS EC2 remains a top choice for developers seeking to deploy their applications.  As an Infrastructure as a Service (IaaS), EC2 frees you from worrying about the physical layer of servers, allowing you to focus on what matters most: your application.

Ready to get started? You'll need these things:

🚀 An AWS account - Your launchpad to the cloud

🐙 A GitHub account

💻 Node.js on your local machine - The engine of your app

🌿 Git installed locally

🧠 Basic know-how of:

🟢 Node.js and Express - The dynamic duo of backend development

🔀 Git

🔐 SSH - The secret handshake of secure connections

🐧 Linux commands - Speaking the language of your server

Benefits of Using AWS EC2 for Node.js

Here are the top 3 benefits of using AWS EC2 for Node.js applications:

1. Scalability

Instantly adjust your app's resources to match demand, ensuring smooth performance during traffic spikes without overpaying for unused capacity.

2. Flexibility

Choose from a variety of instance types optimized for different workloads, allowing you to fine-tune your environment for optimal Node.js performance.

3. Cost-effectiveness

Pay only for the computing power you use, with options to reserve instances for long-term savings, making it budget-friendly for projects of all sizes.

Getting Started with Node.js on EC2

Key Steps for Setting up your Node.js app on AWS EC2

Step 1: Creating an AWS Account

  • Steps to create an AWS account.

Step 2: Verifying Your Identity

  • Completing the necessary verification processes.

Step 3: Launching an EC2 Instance

  • Sign in to AWS Management Console.
  • Launch an EC2 instance with the appropriate AMI.
  • Choose an instance type and configure the instance.
  • Open ports 80 (HTTP) and 443 (HTTPS) in the security group.
  • Set up key pair and launch the instance.

Step 4: Connecting to Your EC2 Instance

  • SSH into the EC2 instance using your key pair.

Step 5: Setting Up and Deploying a Node.js App

  • Install Node.js on the instance.
  • Clone your Node.js app from GitHub.
  • Install required dependencies using npm install.

Setting Up HTTPS (Optional if you don’t want to use HTTPS)

Solution 1: Setcap

  • Use setcap to grant permissions to the Node.js binary to listen on port 443.

Solution 2: Setting Up HTTPS with NginxStep 6: Running the Node.js App

  • Ensure the app runs on the correct port and use a process manager like PM2 to keep the app running.
  • Test your setup by accessing the app over HTTP(S).

Step 6: Running the Node.js App

  • Ensure the app runs on the correct port and use a process manager like PM2 to keep the app running.
  • Test your setup by accessing the app over HTTP(S).

This simplified process allows you to deploy your Node.js app to the cloud efficiently. Each step is essential for setting up a suitable environment for your app on EC2.

Step 2: Verifying Your Identity

After creating your account, AWS will ask you to verify your identity. This typically involves providing a phone number for a verification code. This step is crucial for maintaining the security of your cloud infrastructure and preventing unauthorized access.

Step 3: Launching an EC2 Instance

3.1: Sign in to AWS Management Console:

Navigate to EC2 Dashboard.

3.2:  Select "Launch Instance" to create your new EC2 server.

3.3: Choose an Amazon Machine Image (AMI)

3.4: Choose Instance Type

Choose your server's power:

  • Pick an EC2 instance type that matches your app's requirements
  • For light workloads, a t2.micro is often sufficient
  • Scale up to larger instances for more demanding applications

3.5: Key pair (login)

You can either select or create a New Key Pair.

3.6: Configure Instance

Configure instance settings, including network configurations, storage options, and security groups.

3.7: Add Tags (Optional).

3.8: Configure Security Group

If you want to use HTTPS for your website and have SSL certificates installed on your EC2 instance, ensure port 443 is allowed in your Security Group.

3.9: Review and Launch

3.10: Review your instance configuration and launch the instance

Connecting to Your EC2 Instance

SSH into the Instance


ssh -i /path/to/your-key-pair.pem ec2-user@your-instance-public-dns

Replace the placeholders with your actual key pair path and instance DNS. This command establishes a secure connection to your cloud environment, allowing you to begin setting up your Node.js application.

Setup GitHub and clone your node.js in the ec2 instance


git clone https://github.com/shorterloop/{node-js-demo.git}

Replace the placeholder repository name. If you're using an existing Node.js project, skip the following steps and go directly to step 4 Deploying and Managing Your Application.

Install dependencies and start your app

1. Install node.js using NVM

GitHub-NVM

To install or update nvm, use the following cURL or Wget command:


curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash


wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash

Running either command downloads a script that clones nvm to ~/.nvm and updates the appropriate profile file.


export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

2. Create a Nodejs express app

In your terminal window, paste or type the commands below:


mkdir shorterloop-node-js-ec2-demo
cd shorterloop-node-js-ec2-demo
npm init -y

The -y flag automatically uses default settings.

3. Install the following packages


npm install express dotenv

⏭️ Express is a popular choice for creating web applications with Node.

⏭️ Dotenv loads environment variables from .env file into Node.js's process.env object.

⏭️ npm uses the package.json file to identify a project and manage its dependencies. It includes essential project metadata.


{
  "name": "shorterloop-node-js-ec2-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Write your start script:

Basically, you can kick off your server by running npm start.


{
  "name": "shorterloop-node-js-ec2-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node app.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

⏭️ Create a .env file

Create a .env file at the root, and add the below code: file at the root, add the below code:


PORT=2323

⏭️ Make a new file called app.js and insert the code below


require('dotenv').config(); // Loads .env file
const express = require('express');
const app = express();
const port = process.env.PORT || 3000; // default port is 3000

app.get('/', (req, res) => {
    return res.json({
        message: 'Hello from ShorterLoop!'
    });
});

app.listen(port, () => {
    console.log(`Server running on port ${port}`);
});

⏭️ Start the server

Execute the following command in your terminal:


npm start

⏭️ Push it to GitHub


git add .
git commit -m "Learning express.js ec2 deployment"
git push origin main

4. Deploying and Managing Your Application

To ensure your Node.js app runs smoothly in production, consider using a process manager like PM2. PM2 keeps your application running continuously and can automatically restart it if it crashes.

Here's a quick guide to deploying with PM2:

1. Install PM2 globally:


npm install -g pm2

2. Navigate to your application directory

3. Start your app:


pm2 start app.js

To check if your app is running, use this -


# To check the jobs
pm2 list

# To check your logs
pm2 logs

Access Your Application

Open a web browser and go to your EC2 instance's public IP address or DNS name to access your Node.js application.


http://IPv4_Address:Port

Running node.js app on port 443 (HTTPS)

To deploy a Node.js app on EC2 using HTTPS, you need root privileges to bind to port 443. There are two solutions. Shorter Loop usesolution1.

Solution 1: Grant Node.js the Required Permissions

To let your Node.js app use port 443 without root privileges, use the setcap command to give it the necessary permissions.


sudo setcap 'cap_net_bind_service=+ep' $(readlink -f $(which node))

Solution 2: Use Nginx as a Reverse Proxy

Consider using Nginx as a reverse proxy. It can handle HTTPS, terminate SSL/TLS, and forward requests to your Node.js app on a port that doesn't require root privileges.

Steps to Set Up Nginx as a Reverse Proxy:

1. Install Nginx:

First, install Nginx on your EC2 instance:


sudo apt-get install nginx

2. Configure Nginx:

Create or modify the Nginx configuration file (usually located in /etc/nginx/sites-available/default) to include the following:


server {
    listen 443 ssl;
    server_name your-domain.com;

    ssl_certificate /path/to/your/certificate.pem;
    ssl_certificate_key /path/to/your/privatekey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;  # Replace 3000 with your Node.js app's port
        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;
    }
}

server {
    listen 80;
    server_name your-domain.com;

    return 301 https://$host$request_uri;
}

3. Enable the Site and Restart Nginx:


sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/
sudo nginx -t  # Test the Nginx configuration
sudo systemctl restart nginx

4. Make sure you port 443 is enabled in aws security group.

5. Check the status

After setting up, verify that port 443 is listening:


sudo lsof -i :443
sudo netstat -tuln | grep 443

Conclusion

Congratulations on deploying your Node.js application on AWS EC2 using PM2! This foundation opens up exciting possibilities for your projects. However, remember that AWS charges for active services, so be vigilant about your usage to avoid unexpected costs. Consider using an Elastic IP for a static address, but note that it's only free when associated with a running instance.

As you grow more comfortable with AWS, explore its ecosystem to enhance your app's performance and reliability. The cloud journey is ever-evolving, so keep experimenting and building. Just remember to monitor your resources closely and shut down unused services to keep costs in check.

Your next great innovation awaits – happy cloud computing!