nginx Reverse Proxy and TLS: Upstreams, Headers, and Let’s Encrypt

Put nginx in front of your app with proxy_pass, forward client metadata, redirect HTTP to HTTPS, and outline Certbot for free certificates.

DevOps & infrastructure Advanced 8 min read

·

nginx sits in front of app processes to terminate TLS, enforce timeouts, and map many hostnames to backends. Directives like proxy_set_header X-Forwarded-Proto exist because your app needs to know the original scheme when generating URLs behind TLS termination.

Containers from Docker Compose often publish an internal port; nginx on the host or edge routes public traffic to them.

Basic reverse proxy

Why proxy_pass to 127.0.0.1: Binds traffic to loopback so the app is not exposed on all interfaces without nginx in front.

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

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;
    }
}

Why these headers: The app sees original host and client IP for logs and redirects; X-Forwarded-Proto tells frameworks to generate https:// links.

Security note: Trust these headers only from nginx, not from clients on the open internet.

HTTP to HTTPS redirect

Why redirect port 80: Users and bots still hit http://; a 301 to HTTPS prevents accidental cleartext sessions.

Let’s Encrypt and Certbot (overview)

Why automated TLS: Short-lived certificates reduce breach windows; Certbot renews before expiry if DNS and port 80/443 stay reachable.

  1. Point DNS A/AAAA records to your server.
  2. Install Certbot with the nginx plugin for your OS.
  3. Run certbot --nginx -d app.example.com to obtain and install certificates.
  4. Enable automatic renewal (usually a systemd timer or cron).

Security headers (brief)

Why HSTS after HTTPS works: Tells browsers never to downgrade to HTTP for that host—only enable once TLS is correct.

Frequently asked questions

nginx vs Apache?

Both are mature; nginx is common as a reverse proxy/CDN edge due to event-driven architecture and simple static file serving.

What is proxy_set_header for?

Your backend sees the original host and client IP through headers; without them logs and redirects may show 127.0.0.1.

Can I terminate TLS in Docker instead?

Yes—Traefik, Caddy, or nginx in a container can handle certificates; keep private keys out of images and use mounted secrets.

Why not expose my app port directly?

A proxy adds rate limiting, gzip, TLS, routing to multiple services, and a smaller attack surface for your application process.