April 29, 2026 6 min read

How to Set Up Nginx as a Reverse Proxy on Ubuntu 24

A step-by-step guide to configuring Nginx to forward traffic from port 80 to a Node.js app — including SSL with Certbot and proper firewall setup.

Overview

When you run a Node.js (or any backend) app on a server, it typically listens on a high port like 3000. You can't expose port 3000 to the public directly because it's not standard HTTP/HTTPS. This is where Nginx comes in — as a reverse proxy, it sits in front of your app and forwards incoming requests from port 80 (HTTP) or 443 (HTTPS) to port 3000.

Prerequisites

You need a fresh Ubuntu 24 server, a domain pointed to your server's IP, and a running Node.js app on port 3000. This guide assumes you have SSH access with sudo privileges.

Step 1 — Install Nginx

1 Update your package list and install Nginx
bash
sudo apt update
sudo apt install nginx -y

Once installed, Nginx starts automatically. You can verify it's running with:

bash
sudo systemctl status nginx

Step 2 — Configure the Firewall

2 Allow HTTP and HTTPS traffic through UFW
bash
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status

Nginx Full is a UFW application profile that opens both ports 80 and 443. This is what you want since we'll be adding SSL later.

Step 3 — Create a Server Block

3 Create a new configuration file for your domain

Nginx stores site configurations in /etc/nginx/sites-available/. Create a new file for your domain:

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

Paste the following configuration, replacing yourdomain.com with your actual domain:

nginx
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.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;
    }
}

Now enable the site by creating a symbolic link to sites-enabled:

bash
sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Tip

Always run sudo nginx -t before reloading. It checks the config for syntax errors and saves you from taking the server down with a bad config file.

Step 4 — Add SSL with Certbot

4 Install Certbot and get a free SSL certificate
bash
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot will automatically modify your Nginx config to enable HTTPS and set up automatic certificate renewal. That's it — your app is now accessible over HTTPS.

Verify automatic renewal

Certbot sets up a systemd timer that renews certs before they expire. You can verify it's active with:

bash
sudo systemctl status certbot.timer

Summary

Here's what we did in four steps:

  1. Installed Nginx and verified it's running
  2. Opened ports 80 and 443 through the UFW firewall
  3. Created a server block that proxies traffic to localhost:3000
  4. Secured everything with a free Let's Encrypt SSL certificate

Your Node.js app is now reachable at https://yourdomain.com without exposing its port directly.

J
John Ripdos

Writing tutorials based on real tasks I encounter at work. Everything here is battle-tested and built from experience.