EQVPS

How to set up an nginx reverse proxy with HTTPS

Put a clean domain and automatic HTTPS in front of any app running on a local port. Two ways: nginx with Certbot, or Caddy for automatic TLS in one line. Step-by-step, with the config you can copy.

Most self-hosted apps listen on a local port like 127.0.0.1:3000 and speak plain HTTP. A reverse proxy sits in front on ports 80/443, terminates HTTPS with a real certificate, and forwards traffic to that local port — giving you a clean https://app.yourdomain.com and letting you run several apps behind one IP. Here are both common ways.

Prerequisites

Option A — Caddy (automatic HTTPS, one line)

sudo apt install -y caddy
echo 'app.yourdomain.com { reverse_proxy 127.0.0.1:3000 }' | sudo tee /etc/caddy/Caddyfile
sudo systemctl restart caddy

That's it — Caddy obtains a Let's Encrypt certificate for the domain and renews it automatically.

Option B — nginx + Certbot

sudo apt install -y nginx certbot python3-certbot-nginx

Create /etc/nginx/sites-available/app:

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

Enable it and add HTTPS:

sudo ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d app.yourdomain.com

Certbot edits the config to serve HTTPS and sets up auto-renewal.

Honest cautions

Next steps

A reverse proxy is what lets one box serve many things — see self-hosting multiple services behind one IP. Running the app in a container? Start with how to install Docker. To keep the app itself alive across reboots and crashes, see how to create a systemd service.

FAQ

What is a reverse proxy and why do I need one?

Your app usually listens on a local port like 127.0.0.1:3000. A reverse proxy sits in front on ports 80/443, terminates HTTPS, and forwards requests to that local port. It gives you a clean domain, a valid TLS certificate, and the ability to run several apps behind one IP — none of which your app has to handle itself.

nginx or Caddy — which should I pick?

Caddy is the fastest path: it obtains and renews Let's Encrypt certificates automatically, and a working HTTPS proxy is one line of config. nginx is more widely known and flexible, but you add Certbot for TLS. If you just want HTTPS with minimal fuss, use Caddy; if you already know nginx or need its features, use nginx.

Do I need a domain?

For a trusted HTTPS certificate, yes — Let's Encrypt issues certificates for domain names, not bare IPs. Point an A record at your server's IP, wait for DNS to propagate, then the proxy can obtain a certificate for that name.

What ports need to be open?

80 and 443 inbound. Port 80 is used for the initial certificate challenge and to redirect to HTTPS; 443 serves the encrypted traffic. Open both in your firewall (see the UFW guide) and make sure nothing else is already bound to them.

Why does certificate issuance fail?

Almost always DNS or ports. The domain's A record must point at this server and have propagated, and ports 80/443 must be reachable (open in the firewall, not blocked upstream). Fix those two and issuance succeeds; Caddy and Certbot both retry.

Comments

No comments yet. Be the first.

Leave a comment

Comments are moderated before they appear.