Introducing ZYNOO General Purpose & CPU Optimized Servers   Learn More >

How to Set Up Nginx Reverse Proxy on Ubuntu

An Nginx reverse proxy receives requests from website visitors and forwards them to another server or application. It’s commonly used to make applications running on ports such as 3000 accessible through a domain name, without exposing their internal ports to the internet.

In this tutorial, you’ll configure Nginx on Ubuntu to forward requests to a local application, connect a domain, and enable HTTPS.

What Is an Nginx Reverse Proxy?

A reverse proxy sits between visitors and your backend application.

Instead of connecting directly to an application running on port 3000, visitors connect to Nginx on the standard HTTP or HTTPS ports.

Nginx forwards the request to the application and returns its response.

The request flow looks like this:

Visitor → Nginx → Backend Application

This setup is commonly used for Node.js, Python, and other web applications. It can also support TLS termination, load balancing, and centralized request handling.

Need a VPS for Your Nginx Setup?
Deploy your applications with root access and flexible server resources.
Explore VPS Plans →

Prerequisites

Before starting, you’ll need:

  • An Ubuntu 24.04 LTS server with sudo access.
  • SSH access to your server.
  • A domain name pointing to your server’s public IP address.
  • A backend application listening on a local port.

We’ll use port 3000 in this example.

If you’re new to SSH, read our SSH commands beginner’s guide before continuing.

How to setup Nginx Reverse Proxy

Step 1: Install Nginx on Ubuntu

Connect to your Ubuntu server through SSH.

Update the package index and install Nginx:

sudo apt update
sudo apt install nginx -y

Check whether Nginx is running:

sudo systemctl status nginx

You should see active (running).

If Nginx isn’t started, run:

sudo systemctl enable --now nginx

You can also visit your server’s public IP address in a browser. The default Nginx welcome page should appear if HTTP access is allowed.

If you’re using UFW, allow HTTP and HTTPS traffic:

sudo ufw allow 'Nginx Full'

Also check any firewall rules configured through your hosting provider. Don’t disable the firewall to make Nginx accessible.

Step 2: Start a Test Backend Application

Before configuring the reverse proxy, we need an application for Nginx to forward requests to.

For a simple test, create a temporary directory:

mkdir -p ~/nginx-proxy-test
cd ~/nginx-proxy-test

Create a basic HTML page:

echo '<h1>Nginx Reverse Proxy Works!</h1>' > index.html

Now start Python’s built-in HTTP server:

python3 -m http.server 3000 --bind 127.0.0.1

This serves your test page on port 3000, accessible only through the local loopback address.

Leave this terminal running and open a second SSH session.

Verify that the application responds:

curl http://127.0.0.1:3000

You should see:

<h1>Nginx Reverse Proxy Works!</h1>

This Python server is only for demonstration. For a production application, use its recommended application server and service-management setup.

Step 3: Create an Nginx Reverse Proxy Configuration

Create a new Nginx server block:

sudo nano /etc/nginx/sites-available/app.example.com

Replace app.example.com with your actual domain.

Add the following configuration:

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;

        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;
    }
}

Save the file.

Understanding the Configuration

  • listen 80 accepts HTTP requests.
  • server_name specifies the domain Nginx should handle.
  • proxy_pass forwards requests to the application on port 3000.
  • proxy_set_header passes useful information about the original request to the backend.

The backend must understand and safely handle forwarded headers. Only configure applications to trust these headers when requests arrive through your trusted proxy.

Step 4: Enable and Test the Configuration

Enable your new server block:

sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/

If the link already exists, don’t recreate it.

Check the configuration for errors:

sudo nginx -t

If the test succeeds, reload Nginx:

sudo systemctl reload nginx

Now open:

http://app.example.com

If DNS is pointing to the correct server and the test backend is still running, you should see:

Nginx Reverse Proxy Works!

If the default Nginx page appears instead, check your domain’s DNS records and server_name configuration.

Step 5: Enable HTTPS with Let’s Encrypt

For a public website, use HTTPS rather than leaving traffic unencrypted.

First, confirm your domain resolves to the correct server and that inbound port 80 is accessible. These are important for the standard HTTP certificate-validation process.

Install Certbot using the official Snap-based approach:

sudo snap install --classic certbot

If the certbot command isn’t already available, create the command link:

sudo ln -s /snap/bin/certbot /usr/local/bin/certbot

Then request a certificate:

sudo certbot --nginx -d app.example.com

Follow the prompts. Certbot can obtain a certificate and configure Nginx to serve your domain over HTTPS.

Afterward, test certificate renewal:

sudo certbot renew --dry-run

Visit:

https://app.example.com

Your test application should now load through an encrypted connection.

Step 6: Verify Your Reverse Proxy

Check the HTTPS response:

curl -I https://app.example.com

For the example Python backend, an HTTP 200 OK response indicates that the request reached the application successfully.

You can also check which processes are listening on your server:

sudo ss -ltnp

Your Nginx installation should listen on the configured public HTTP and HTTPS ports, while the example backend listens on 127.0.0.1:3000.

Remember that the temporary Python server will stop when you terminate its terminal session. Production applications should run under a process supervisor such as systemd.

Common Nginx Reverse Proxy Problems

502 Bad Gateway

This usually means Nginx couldn’t receive a valid response from the backend.

Check that your application is running and that the port in proxy_pass is correct.

504 Gateway Timeout

A 504 error occurs when the gateway doesn’t receive the required upstream response in time.

Investigate slow application requests and backend performance before increasing timeouts.

The Domain Doesn’t Load

Check that your domain’s A record points to the correct public IP address, the relevant firewall ports are open, and the Nginx server block matches the requested hostname.

Frequently Asked Questions

What is proxy_pass in Nginx?

proxy_pass tells Nginx where to forward requests, such as an HTTP application running on 127.0.0.1:3000.

Can Nginx reverse proxy multiple applications?

Yes. You can configure separate domains, subdomains, or URL paths to forward requests to different backend applications.

Do I need a domain for an Nginx reverse proxy?

No. You can test a reverse proxy with an IP address or locally. However, a domain makes public hosting and obtaining a standard HTTPS certificate more straightforward.

Is Nginx reverse proxy free?

Yes. Open-source Nginx supports reverse proxy functionality without requiring a commercial license.

Conclusion

You’ve configured an Nginx reverse proxy on Ubuntu, forwarded requests to a local application, and enabled HTTPS.

The same basic configuration can be adapted for Node.js, Python, and other HTTP-based applications by updating the backend address in proxy_pass.

Before using the setup in production, ensure your application starts automatically, runs under appropriate permissions, and has adequate monitoring and security controls.

Table of Content

A 502 Bad Gateway error in Nginx usually means Nginx couldn’t receive a valid response

A 504 Gateway Timeout error occurs when a server acting as a gateway or proxy

An MCP server is a program that allows AI applications to connect with external tools,

Build your next project with ZYNOO

From your first website to demanding applications, choose the resources and control you need.

Shared Hosting

Start your blog or business website with cPanel, LiteSpeed and CloudLinux.

VPS Hosting

Grow your websites and applications with NVMe storage, KVM virtualization and full root access.

Dedicated Servers

Power demanding projects with your own physical server, dedicated resources and control over your environment.

Scroll to Top