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
/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).
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.
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.
# 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;