# 🚀 Deploying a Node.js App on AWS EC2 with PM2 and NGINX (Day 22 of #90DaysOfCloud)

Today’s cloud journey was all about **building and hosting a Node.js application** from scratch on an **AWS EC2 instance**, without using Docker. I went from provisioning the server to configuring the application and making it available through a web browser — using **PM2** for background processing and **NGINX** as a reverse proxy.

Let’s go step-by-step 👇

---

## ☁️ Part 1: Launching the EC2 Instance

1️⃣ **Go to AWS EC2 Console → Launch Instance**  
2️⃣ **Choose AMI:**

* Amazon Linux 2 (Free tier eligible)
    

3️⃣ **Choose Instance Type:**

* `t2.micro` (Free tier)
    

4️⃣ **Configure Key Pair:**

* Create or use existing key pair (e.g., `my-key.pem`)
    

5️⃣ **Configure Security Group (Allow only):**

* Port 22 (SSH) — Your IP only
    
* Port 80 (HTTP) — Anywhere
    
* (Optional) Port 3000 — for direct app testing
    

6️⃣ **Launch the instance**

---

## 🔐 Part 2: SSH into EC2 Instance

After launching:

```bash

ssh -i "my-key.pem" ec2-user@<your-ec2-public-ip>
```

Replace `<your-ec2-public-ip>` with your EC2 instance’s public IP.

---

## 🧱 Part 3: Install Node.js and NPM

Update system and install required packages:

```bash
sudo yum update -y
sudo yum install nodejs -y
sudo yum install npm -y
```

Verify installation:

```bash
node -v
npm -v
```

---

## 🗂️ Part 4: Create Your Node.js Application

### Step 1: Create Project Directory

```bash
mkdir nodeapp
cd nodeapp
```

### Step 2: Initialize and Create Files

#### Create `package.json`

```bash
vim package.json
```

Paste:

```bash
jsonCopyEdit{
  "name": "nodeapp",
  "version": "1.0.0",
  "description": "Simple Node.js App",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  }
}
```

#### Create `app.js`

```bash
vim app.js
```

Paste:

```bash
javascriptCopyEditconst express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello from Node.js app on EC2!');
});

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

### Step 3: Install Dependencies

```bash
npm install
```

---

## 🌐 Part 5: Test the Application

Run the app:

```bash
node app.js
```

Open browser and visit:

```bash
http://<your-ec2-public-ip>:3000
```

If it works, press `Ctrl + C` to stop it for now.

---

## 🔄 Part 6: Run App in Background using PM2

### Step 1: Install PM2 globally

```bash
sudo npm install -g pm2
```

### Step 2: Start the app using PM2

```bash
pm2 start app.js
```

### Step 3: Auto-start on reboot

```bash
pm2 startup
```

Follow the command it gives you (usually something like `sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u ec2-user --hp /home/ec2-user`)

Then run:

```bash
pm2 save
```

App will now persist across reboots!

---

## 🌐 Part 7: Configure NGINX as Reverse Proxy

### Step 1: Install NGINX

```bash
sudo yum install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx
```

### Step 2: Edit NGINX Config

```bash
sudo vim /etc/nginx/nginx.conf
```

In the `server` block, add this inside the `location /`:

```bash
location / {
    proxy_pass http://localhost:3000;
}
```

Example section:

```bash
server {
    listen       80;
    server_name  localhost;

    location / {
        proxy_pass http://localhost:3000;
    }
}
```

### Step 3: Restart NGINX

```bash
sudo systemctl restart nginx
```

---

## ✅ Final Result

Now you can visit:

```bash
http://<your-ec2-public-ip>
```

🎉 You should see: `Hello from Node.js app on EC2!`

---

## 🔐 Tips & Best Practices

* Open only required ports in security groups (22, 80)
    
* Use **PM2** for production-grade Node.js app management
    
* Use **NGINX** to proxy requests (avoid exposing port 3000)
    
* Backup your key file (`my-key.pem`) safely
    
* Enable auto-restart on reboot with `pm2 startup && pm2 save`
    

---

## ✅ Summary

On **Day 22**, I learned to:

* Launch an EC2 instance from scratch
    
* Install and configure Node.js and NGINX
    
* Serve an app via PM2 and expose it with a clean public URL
    
* Use Linux terminal, Vim, and systemctl efficiently
    

---

## 📅 What’s Next?

On **Day 23**, I’ll be deploying a **Python Flask application** on an EC2 instance — just like we did with Node.js.

🔧 I’ll cover:

* Installing Python & pip on EC2
    
* Setting up a Flask web app
    
* Running it in the background with **Gunicorn** or **PM2**
    
* Exposing it using **NGINX as a reverse proxy**
    
* Securing ports and handling multiple app deployments
    

This will strengthen my experience in hosting apps using different backends and prepare me for multi-language DevOps workflows! 🚀
