GhostVPSghostvps.shop Open Panel

← Blog

Guide

How to set up Nginx as a reverse proxy with free SSL

June 23, 2026 ~8 min read NginxSSLUbuntu

Most real web applications should not be exposed directly to the internet on ports like 3000, 5000, or 8000. A cleaner production setup is to run the app on a private local port and place Nginx in front of it. Nginx receives public traffic, forwards requests to your app, and handles HTTPS, domain routing, headers, and basic operational polish.

Contents

  1. Why use Nginx as a reverse proxy?
  2. What you need before starting
  3. Install and check Nginx
  4. Open the firewall
  5. Create the reverse proxy config
  6. Enable free SSL with Certbot
  7. Common errors and fixes
  8. Production checklist
  9. FAQ

1. Why use Nginx as a reverse proxy?

A reverse proxy sits between users and your application. Users connect to https://example.com, Nginx accepts the request on ports 80 and 443, and then Nginx passes that request to your application running locally, such as 127.0.0.1:3000.

This pattern is useful for Node.js, Django, Flask, FastAPI, Laravel, Rails, Go, and almost any HTTP service. It lets your app focus on application logic while Nginx handles the public edge.

Need a VPS for your app?

Deploy a cloud server in minutes and pay with Bitcoin, Monero, or USDT. No KYC, no bank card.

Deploy a VPS

2. What you need before starting

This guide assumes you have a fresh Ubuntu VPS and SSH access. You also need a domain or subdomain pointed to your server IP address with an A record.

In the examples below, replace these values with your own:

example.com        # your domain
www.example.com    # optional www version
127.0.0.1:3000     # your app's local address and port
Before running Certbot, your domain should already load over plain HTTP on port 80. This lets Let's Encrypt verify that you control the domain.

3. Install and check Nginx

Update the server and install Nginx:

sudo apt update
sudo apt install nginx -y

Check that the service is running:

sudo systemctl status nginx

You can also visit your server IP in a browser:

http://YOUR_SERVER_IP

If Nginx installed correctly, you should see the default welcome page. That page is temporary; your custom domain config will replace it.

4. Open the firewall

If you use UFW, allow SSH first so you do not lock yourself out. Then allow HTTP and HTTPS:

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status

Only open ports your server actually needs. For a normal web app behind Nginx, public access usually needs 22 for SSH, 80 for HTTP validation/redirects, and 443 for HTTPS.

5. Create the reverse proxy config

Create a new Nginx server block:

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

Add this configuration:

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

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

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

Enable the site by linking it into sites-enabled:

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

Test the Nginx syntax before reloading:

sudo nginx -t
sudo systemctl reload nginx

Now visit http://example.com. If your app is running on 127.0.0.1:3000, Nginx should forward traffic to it.

What the proxy headers do

The proxy_set_header lines preserve useful request information. Your app can see the original host, the visitor's IP address, and whether the request came over HTTP or HTTPS. Many frameworks use these values for logs, redirects, and absolute URL generation.

6. Enable free SSL with Certbot

Certbot can request a free Let's Encrypt certificate and update your Nginx config automatically. Install it with Snap:

sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Run Certbot for your domain:

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

Follow the prompts. Certbot will verify the domain, install the certificate, and can configure HTTP-to-HTTPS redirects for you.

Test automatic renewal:

sudo certbot renew --dry-run

If the dry run succeeds, renewal is ready. Certbot installs a timer that periodically renews certificates before they expire.

7. Common errors and fixes

502 Bad Gateway

Nginx is reachable, but your app is not. Check whether the app is running and listening on the configured port:

sudo ss -tulpn | grep 3000
curl -I http://127.0.0.1:3000

If the app listens on a different port, update proxy_pass and reload Nginx.

Certbot cannot verify the domain

Check DNS and firewall rules. Your domain must point to this server, and port 80 must be reachable from the internet:

dig +short example.com
sudo ufw status

Nginx reload fails

Run a syntax test and read the exact error line:

sudo nginx -t

The most common causes are a missing semicolon, duplicate server_name config, or a symlink pointing to the wrong file.

The app redirects to HTTP after SSL

Your framework may not trust reverse proxy headers by default. Make sure it reads X-Forwarded-Proto and knows it is behind a proxy. The exact setting depends on your framework.

8. Production checklist

Keep your app service bound to localhost unless it truly needs public access. If both Nginx and the app are public, you lose one of the main benefits of the reverse proxy setup.

FAQ

Do I need Nginx if my app already has a built-in web server?
For production, usually yes. Nginx gives you HTTPS handling, redirects, public routing, logging, buffering, and a stable entry point while your app runs on a private local port.
Can I host multiple apps on one VPS?
Yes. Create one Nginx server block per domain or subdomain, then proxy each one to a different local port.
Why does Certbot need port 80?
The standard HTTP validation flow requires Let's Encrypt to reach your server over port 80 before issuing or renewing the certificate. DNS validation is the alternative when that is not possible.
What does 502 Bad Gateway mean?
It usually means Nginx is working but cannot reach your application. Check the app process, port, and the address used in proxy_pass.

Further reading


GhostVPS is an anonymous, no-KYC VPS host on real DigitalOcean infrastructure. Pay with Bitcoin, Monero or USDT (TRC20); deploy in minutes from $6/mo. See pricing or open the panel.