Nginx reverse proxy setup on ubuntu

Launch ubuntu instance on aws

Install node.js

# Download and install nvm:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash

# in lieu of restarting the shell
\. "$HOME/.nvm/nvm.sh"

# Download and install Node.js:
nvm install 22

# Verify the Node.js version:
node -v # Should print "v22.15.0".
nvm current # Should print "v22.15.0".

# Verify npm version:
npm -v # Should print "10.9.2".
mkdir demo
cd demo

1. Basic Node.js HTTP Server (Express.js)

Create server.js file under demo folder

// server.js
const express = require('express');
const app = express();
const PORT = 3000;

app.get('/', (req, res) => {
  res.send('Hello from Node.js backend! πŸš€');
});

app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}`);
});

How to Run:

  1. Install Express

     npm init -y
     npm install express
    
  2. Start the server:

     node server.js
    
  3. Test it:

  4. PM2 (Production Process Manager)

    For running Node.js in the background (useful for production):

     npm install pm2 -g
     pm2 start server.js
     pm2 save
     pm2 startup  # Auto-start on server reboot
    
pm2 stop server.js

Key PM2 Commands:

CommandDescription
pm2 listList all running processes
pm2 logsView real-time logs
pm2 restart <app_name>Restart an app
pm2 stop <app_name>Stop an app
pm2 delete <app_name>Remove an app from PM2

pm2 start server.js

Go to godaddy dns management section and map public ip of ubuntu server with the domain name

Edit A Record and CNAME record

Step 1: Install NGINX

sudo apt update
sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx

Verify NGINX is running:

systemctl status nginx

(Should see active (running))

Step 2: Configure NGINX as a Reverse Proxy

Edit the default NGINX config or create a new one:

sudo nano /etc/nginx/sites-available/yourdomain.com.conf

Basic Reverse Proxy Example

Replace yourdomain.com with your actual domain and backend server.

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    location / {
        proxy_pass http://localhost:3000;  # Your backend server
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

HTTPS with Let’s Encrypt

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

(Follow prompts to enable HTTPS.)


Step 3: Enable the Configuration

  1. Link the config file:

     sudo ln -s /etc/nginx/sites-available/yourdomain.conf /etc/nginx/sites-enabled/
    
  2. Test NGINX config:

     sudo nginx -t
    

    (Should say syntax is OK.)

  3. Restart NGINX:

     sudo systemctl restart nginx
    

Step 4: Verify the Reverse Proxy

  1. Access your domain https://yourdomain.comor https://www.yourdomain.com in a browser.

  2. Check NGINX logs for errors:

     sudo tail -f /var/log/nginx/error.log
    

    Advanced Example (With Routes & Middleware)

    edit server.js

     const express = require('express');
     const app = express();
     const PORT = 3000;
    
     // Middleware (Parse JSON requests)
     app.use(express.json());
    
     // Routes
     app.get('/', (req, res) => {
       res.send('Home Page');
     });
    
     app.get('/api', (req, res) => {
       res.json({ message: 'API Response', status: 200 });
     });
    
     app.post('/api/login', (req, res) => {
       const { username, password } = req.body;
       res.json({ user: username, auth: true });
     });
    
     // Start Server
     app.listen(PORT, () => {
       console.log(`Node.js server running on http://localhost:${PORT}`);
     });
    
     pm2 stop server.js
     pm2 start server.js
    
  3. Test with curl:

     curl http://<public-ip>:3000
     # Output: "Home Page"
    
     curl http://<public-ip>:3000/api
     # Output: {"message":"API Response","status":200}
    
     curl -X POST -H "Content-Type: application/json" -d '{"username":"admin","password":"123"}' http://<public-ip>:3000/api/login
     # Output: {"user":"admin","auth":true}
    
0
Subscribe to my newsletter

Read articles from SRINIVAS TIRUNAHARI directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

SRINIVAS TIRUNAHARI
SRINIVAS TIRUNAHARI