Nginx Web Server SSL Reverse Proxy

Nginx: Complete Server Setup, SSL, and Reverse Proxy Guide

TW
Thomas Weber
Backend Infrastructure Engineer
Sep 15, 2025
20 min read

What You'll Learn

How to set up Nginx as a web server and reverse proxy, configure SSL/TLS with Certbot, manage virtual hosts, and optimize for production.

Why Nginx?

Nginx (pronounced "engine-x") is a high-performance web server, reverse proxy, and load balancer. It uses an asynchronous, event-driven architecture, making it incredibly fast and capable of handling tens of thousands of concurrent connections with low memory usage.

Basic Architecture & Files

bash — Nginx paths (Ubuntu/Debian)
/etc/nginx/
├── nginx.conf              # Main configuration file
├── sites-available/        # Virtual host configurations (VHosts)
└── sites-enabled/          # Symlinks to active VHosts

# Logs
/var/log/nginx/access.log   # All HTTP requests
/var/log/nginx/error.log    # Errors and startup issues

# Commands
sudo systemctl status nginx
sudo nginx -t               # Test config for syntax errors!
sudo systemctl reload nginx # Apply changes without dropping connections

Serving Static Files (Web Server)

Here is a configuration for a basic static HTML website (e.g., a React/Vue SPA build).

/etc/nginx/sites-available/mysite.com.conf
server {
    listen 80;
    server_name mysite.com www.mysite.com;
    
    root /var/www/mysite/html;
    index index.html;

    # React/Vue SPA routing rule (fallback to index.html)
    location / {
        try_files $uri $uri/ /index.html;
    }

    # Browser caching for static assets
    location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }
}

Reverse Proxy (Node.js/Python/Docker)

In modern architectures, Nginx sits in front of your application server (like Node.js running on port 3000) and forwards requests to it. This provides security, SSL termination, and static file caching.

/etc/nginx/sites-available/api.mysite.com.conf
server {
    listen 80;
    server_name api.mysite.com;

    location / {
        proxy_pass http://localhost:3000;  # Forward to Node app
        
        # Pass real client IP to the backend application
        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;
        
        # WebSocket support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Adding SSL with Let's Encrypt (Certbot)

Securing your site with HTTPS is free and takes two minutes using Certbot.

bash
# 1. Install Certbot
sudo apt install certbot python3-certbot-nginx

# 2. Run Certbot (it will auto-detect your Nginx configs)
sudo certbot --nginx -d mysite.com -d www.mysite.com -d api.mysite.com

# Certbot automatically edits your Nginx config to:
# - Add SSL certificates
# - Listen on port 443
# - Add HTTP -> HTTPS redirection

# 3. Verify auto-renewal timer is active
sudo systemctl status certbot.timer

Production Security Headers

Add these inside your server {} block to drastically improve your site's security score.

# Hide Nginx version number
server_tokens off;

# Prevent Clickjacking
add_header X-Frame-Options "SAMEORIGIN" always;

# Prevent MIME type sniffing
add_header X-Content-Type-Options "nosniff" always;

# Enable strict XSS protection
add_header X-XSS-Protection "1; mode=block" always;

# Enforce HTTPS (HSTS)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Keep Reading

D
DevOps

Docker Networking Demystified: Bridge, Host & Overlay

8 min read Read More
C
Cloud

AWS IAM Roles vs Users vs Policies

10 min read Read More
P
Programming

Understanding Python's GIL & Multiprocessing

14 min read Read More