Reverse Proxy • Port Forwarding • Doc
■ Production Ready
■ SSL/TLS Ready
■ Docker Friendly
Table of Contents
1. Nginx ■■? – ■■■■■■ ■ Architecture
2. Installation – Ubuntu / Debian / CentOS / Docker
3. Core Configuration – [Link] ■■■■■■■■
4. Static File Serving
5. Reverse Proxy – ■■■■■■■■ ■■■■
6. Port Forwarding
7. Virtual Hosts / Server Blocks
8. SSL/TLS – Let's Encrypt ■■■■■ HTTPS
9. Load Balancing
10. Docker ■■■■ Nginx
11. Docker Compose – Full Stack Example
12. Security Best Practices
13. Performance Tuning
14. Common Directives Cheat Sheet
15. Troubleshooting
1. Nginx ■■? – ■■■■■■ ■ Architecture
Nginx (Engine-X ■■■■ ■■■■■■■■) ■■■■ high-performance, open-source web server, reverse
proxy, load balancer ■■■ HTTP cache■ 2004 ■■■■ Igor Sysoev ■■■■ ■■■■■ C10K problem
(■■■■■■ ■■,■■■ connection) solve ■■■■ ■■■■ event-driven, non-blocking architecture ■■■■■■■
■■■■
Nginx ■■ ■■ ■■■■ ■■■■?
Feature Description
Web Server Static files serve ■■■ (HTML, CSS, JS, images)
Reverse Proxy Client request ■■■■ server-■ forward ■■■
Load Balancer Multiple backend servers-■ traffic distribute ■■■
SSL Termination HTTPS handle ■■■ backend-■ plain HTTP ■■■■■■
HTTP Cache Response cache ■■■ performance ■■■■■■■
Port Forwarding ■■■■ port-■■ traffic ■■■■ port/server-■ ■■■■■■
API Gateway Microservice architecture-■ central entry point
Apache vs Nginx
Apache thread-based model ■■■■■■■ ■■■ – ■■■■■ connection-■ ■■■■ thread ■■■■ ■■■■
Nginx event-driven model ■■■■■■■ ■■■ – ■■■■ process ■■■■■ ■■■■■ connection ■■■■■■
handle ■■■■ ■■■■■
Apache Nginx
Architecture Thread/Process per conn Event-driven, async
Memory Usage ■■■■ ■■
Static Files ■■■■ ■■■■ ■■■■ (faster)
Dynamic Content mod_php ■■■■■ ■■■■■ FastCGI/proxy ■■■■■
Config .htaccess support Centralized config
Concurrency ■■ (C10K problem) ■■■■ ■■■■
2. Installation
Ubuntu / Debian
# System update ■■■
sudo apt update && sudo apt upgrade -y
# Nginx install ■■■
sudo apt install nginx -y
# Service start ■■■
sudo systemctl start nginx
sudo systemctl enable nginx # boot-■ auto-start
# Status check ■■■
sudo systemctl status nginx
# Firewall allow ■■■
sudo ufw allow 'Nginx Full' # HTTP + HTTPS
sudo ufw allow 'Nginx HTTP' # ■■■■ HTTP
sudo ufw allow 'Nginx HTTPS' # ■■■■ HTTPS
CentOS / RHEL / Rocky Linux
sudo yum install epel-release -y
sudo yum install nginx -y
# ■■■■ Rocky/AlmaLinux-■:
sudo dnf install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx
Version Check ■ Important Paths
nginx -v # version check
nginx -V # ■■ compile options ■■■■
# Important file paths (Ubuntu/Debian):
/etc/nginx/[Link] # main config
/etc/nginx/sites-available/ # ■■ site configs
/etc/nginx/sites-enabled/ # active site configs (symlinks)
/etc/nginx/conf.d/ # extra configs
/var/www/html/ # default web root
/var/log/nginx/[Link] # access logs
/var/log/nginx/[Link] # error logs
/run/[Link] # PID file
Nginx Commands
Command ■■■
sudo nginx -t Config syntax check (deploy ■■■■ ■■■ ■■■■■■!)
sudo systemctl reload nginx Config reload (downtime ■■■)
sudo systemctl restart nginx Full restart
sudo systemctl stop nginx Stop ■■■
sudo nginx -s reload Signal ■■■■■ reload
sudo nginx -s quit Graceful shutdown
sudo nginx -s stop Fast shutdown
3. Core Configuration – [Link] ■■■■■■■■
[Link] ■■ structure ■■■■■ main block-■ ■■■■■■: main, events, http■
# /etc/nginx/[Link]
# ■■ MAIN CONTEXT ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
user www-data; # ■■■ user-■ run ■■■■
worker_processes auto; # CPU core ■■■■■■■■ worker
error_log /var/log/nginx/[Link] warn;
pid /run/[Link];
# ■■ EVENTS CONTEXT ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
events {
worker_connections 1024; # ■■■■■ worker ■■■■■■■■ connections
use epoll; # Linux-■ best event model
multi_accept on; # ■■■■■■ ■■■■ connection accept
}
# ■■ HTTP CONTEXT ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
http {
include /etc/nginx/[Link];
default_type application/octet-stream;
# Log format
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log /var/log/nginx/[Link] main;
sendfile on; # kernel-level file transfer
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
gzip on;
# Include ■■ site configs
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
# ■■ SERVER BLOCK (Virtual Host) ■■■■■■■■■■■■■■■■■■
server {
listen 80;
server_name [Link] [Link];
root /var/www/html;
index [Link] [Link];
location / {
try_files $uri $uri/ =404;
}
}
}
4. Static File Serving
server {
listen 80;
server_name [Link] [Link];
root /var/www/mysite;
index [Link];
# Static files serve ■■■
location / {
try_files $uri $uri/ =404;
}
# Image caching (1 ■■■)
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# CSS/JS caching (30 ■■■)
location ~* \.(css|js)$ {
expires 30d;
add_header Cache-Control "public";
}
# Hidden files block ■■■
location ~ /\. {
deny all;
}
# Directory listing (■■■■■ on ■■■)
location /files/ {
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
}
}
5. Reverse Proxy – ■■■■■■■■ ■■■■
Reverse proxy ■■■■ ■■■ Nginx client-■■ request ■■■■■ backend server-■ ■■■■■■, response
■■■■■ client-■■ ■■■■■ Client ■■■■■ ■■ ■■■■■ ■■■■ server ■■■■
Basic Reverse Proxy
server {
listen 80;
server_name [Link];
location / {
proxy_pass [Link] # backend port
# Headers ■■■■■ backend-■
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;
}
}
Complete Reverse Proxy (Production)
# /etc/nginx/sites-available/[Link]
upstream backend {
server [Link]:3000;
}
server {
listen 80;
server_name [Link] [Link];
# ■■ HTTP → HTTPS redirect
return 301 [Link]
}
server {
listen 443 ssl http2;
server_name [Link] [Link];
ssl_certificate /etc/letsencrypt/live/[Link]/[Link];
ssl_certificate_key /etc/letsencrypt/live/[Link]/[Link];
# Security headers
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000" always;
# Buffer settings
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
# Timeout settings
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
location / {
proxy_pass [Link]
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Real IP forward
proxy_set_header Host $http_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;
# Cache bypass
proxy_cache_bypass $http_upgrade;
}
# Static files directly serve ■■■ (backend bypass)
location /static/ {
alias /var/www/myapp/static/;
expires 30d;
}
# Upload size limit
client_max_body_size 50M;
}
Multiple Apps – ■■■■ Server-■ ■■■■ App
# App 1: [Link] → port 3000
server {
listen 80;
server_name [Link];
location / {
proxy_pass [Link]
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# App 2: [Link] → port 4000
server {
listen 80;
server_name [Link];
location / {
proxy_pass [Link]
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# App 3: [Link] → port 5000
server {
listen 80;
server_name [Link];
# IP restriction (optional)
allow [Link]/24;
deny all;
location / {
proxy_pass [Link]
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Path-based Routing
# ■■■■ domain-■ path ■■■■■■■■ ■■■■■ backend
server {
listen 80;
server_name [Link];
# / → frontend (React/Vue)
location / {
proxy_pass [Link]
proxy_set_header Host $host;
}
# /api/ → backend API (Node/Django/Laravel)
location /api/ {
proxy_pass [Link]
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# /ws/ → WebSocket server
location /ws/ {
proxy_pass [Link]
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
# /media/ → media server
location /media/ {
proxy_pass [Link]
}
}
6. Port Forwarding
Port forwarding ■■■■ ■■■■ port-■ ■■■ traffic ■■■■ port ■■ server-■ ■■■■■■■ Nginx-■ ■■■
HTTP ■■■ TCP/UDP ■■■■■ ■■■ ■■■■■
HTTP Port Forwarding (Port 80 → ■■■■ Port)
# Port 80 → Port 8080
server {
listen 80;
server_name [Link];
location / {
proxy_pass [Link]
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
TCP/UDP Port Forwarding (stream module)
# /etc/nginx/[Link] ■ ■■■ ■■■ (http block ■■ ■■■■■)
stream {
# TCP: Port 3306 → MySQL (■■■■ server)
server {
listen 3306;
proxy_pass [Link]:3306;
proxy_timeout 300s;
proxy_connect_timeout 10s;
}
# TCP: Port 6379 → Redis
server {
listen 6379;
proxy_pass [Link]:6380;
}
# UDP: DNS forwarding
server {
listen 53 udp;
proxy_pass [Link]:53;
proxy_timeout 1s;
proxy_responses 1;
}
# Load balancing with TCP
upstream mysql_servers {
server [Link]:3306;
server [Link]:3306;
}
server {
listen 3307;
proxy_pass mysql_servers;
}
}
Port 443 ■■■■ Internal Port Forwarding
# HTTPS traffic forward ■■■ internal service-■
server {
listen 443 ssl;
server_name [Link];
ssl_certificate /etc/ssl/certs/[Link];
ssl_certificate_key /etc/ssl/private/[Link];
location / {
proxy_pass [Link]
proxy_ssl_verify off; # internal self-signed cert ■■■
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
External to Internal Network Forwarding
# Internet ■■■■ ■■■ traffic → Internal server
# (DMZ setup)
stream {
upstream internal_web {
server [Link]:80; # internal server 1
server [Link]:80; # internal server 2
}
server {
listen 80;
proxy_pass internal_web;
proxy_timeout 600s;
}
}
7. Virtual Hosts / Server Blocks
■■■■ server-■ ■■■ IP ■■■■■ ■■■■ domain host ■■■■ ■■■■■■■
# Step 1: Config file ■■■■ ■■■
sudo nano /etc/nginx/sites-available/[Link]
# ■■ Config content ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
server {
listen 80;
listen [::]:80; # IPv6 support
server_name [Link] [Link];
root /var/www/[Link]/html;
index [Link] [Link];
access_log /var/log/nginx/[Link];
error_log /var/log/nginx/[Link];
location / {
try_files $uri $uri/ =404;
}
}
# Step 2: Symlink ■■■■ ■■■ (enable ■■■)
sudo ln -s /etc/nginx/sites-available/[Link] /etc/nginx/sites-enabled/
# Step 3: Test ■ reload
sudo nginx -t
sudo systemctl reload nginx
# Step 4: Web root ■■■■ ■■■
sudo mkdir -p /var/www/[Link]/html
sudo chown -R $USER:$USER /var/www/[Link]/html
8. SSL/TLS – Let's Encrypt ■■■■■ HTTPS
# Certbot install ■■■
sudo apt install certbot python3-certbot-nginx -y
# SSL certificate ■■■ (auto nginx config)
sudo certbot --nginx -d [Link] -d [Link]
# Manual certificate (nginx config ■■■■ ■■■■)
sudo certbot certonly --nginx -d [Link]
# Certificate renew test
sudo certbot renew --dry-run
# Auto renew cron job (certbot automatically ■■■)
# /etc/cron.d/certbot ■ ■■■
Manual SSL Config
server {
listen 443 ssl http2;
server_name [Link] [Link];
ssl_certificate /etc/letsencrypt/live/[Link]/[Link];
ssl_certificate_key /etc/letsencrypt/live/[Link]/[Link];
ssl_trusted_certificate /etc/letsencrypt/live/[Link]/[Link];
# SSL settings (Mozilla Intermediate)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_stapling on;
ssl_stapling_verify on;
resolver [Link] [Link] valid=300s;
root /var/www/mysite;
index [Link];
location / {
try_files $uri $uri/ =404;
}
}
# HTTP → HTTPS redirect
server {
listen 80;
server_name [Link] [Link];
return 301 [Link]
}
9. Load Balancing
http {
# ■■ Round Robin (default) ■■■■■■■■■■■■■■■■■■■■■■■■■
upstream myapp_rr {
server [Link]:8080;
server [Link]:8080;
server [Link]:8080;
}
# ■■ Weighted Round Robin ■■■■■■■■■■■■■■■■■■■■■■■■■■
upstream myapp_weighted {
server [Link]:8080 weight=5; # ■■■■ traffic ■■■■
server [Link]:8080 weight=2;
server [Link]:8080 weight=1;
}
# ■■ Least Connections ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
upstream myapp_lc {
least_conn;
server [Link]:8080;
server [Link]:8080;
}
# ■■ IP Hash (session persistence) ■■■■■■■■■■■■■■■■■
upstream myapp_iphash {
ip_hash;
server [Link]:8080;
server [Link]:8080;
server [Link]:8080 backup; # backup server
}
# ■■ Health Check ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
upstream myapp_health {
server [Link]:8080 max_fails=3 fail_timeout=30s;
server [Link]:8080 max_fails=3 fail_timeout=30s;
server [Link]:8080 backup;
}
server {
listen 80;
server_name [Link];
location / {
proxy_pass [Link]
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
10. Docker ■■■■ Nginx
Docker-■ Nginx ■■■■■■■ ■■■■■■■ ■■■ ■■■■: (■) Nginx ■■■■■ Docker container-■, (■) Nginx
host-■ ■■■■ Docker container-■■■■■ reverse proxy ■■■■■■ ■■■ ■■■■
Method 1: Nginx Docker Container
# Basic Nginx container ■■■■■
docker run -d \
--name nginx \
-p 80:80 \
-p 443:443 \
nginx:alpine
# Custom config ■■■■■ ■■■■■
docker run -d \
--name nginx \
-p 80:80 \
-v /path/to/[Link]:/etc/nginx/[Link]:ro \
-v /path/to/html:/usr/share/nginx/html:ro \
nginx:alpine
# Logs ■■■■
docker logs nginx
docker logs -f nginx # live logs
Nginx ■■■■■ Docker Apps Proxy ■■■ (Host Nginx)
# Docker app ■■■■■ (port expose ■■■)
docker run -d \
--name my-node-app \
-p 3000:3000 \
my-node-image
docker run -d \
--name my-python-app \
-p 5000:5000 \
my-python-image
# Host-■ nginx config:
# /etc/nginx/sites-available/[Link]
server {
listen 80;
server_name [Link];
location / {
proxy_pass [Link]
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;
}
}
server {
listen 80;
server_name [Link];
location / {
proxy_pass [Link]
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Custom Nginx Dockerfile
# Dockerfile
FROM nginx:alpine
# Default config ■■■■
RUN rm /etc/nginx/conf.d/[Link]
# Custom config copy ■■■
COPY [Link] /etc/nginx/[Link]
COPY conf.d/ /etc/nginx/conf.d/
# Static files copy ■■■
COPY html/ /usr/share/nginx/html/
# Port expose ■■■
EXPOSE 80 443
# Health check
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget -q --spider [Link] || exit 1
CMD ["nginx", "-g", "daemon off;"]
11. Docker Compose – Full Stack Example
Real-world ■■■■■■: React frontend + [Link] API + PostgreSQL + Nginx
[Link]
version: '3.8'
services:
# ■■ Nginx (Reverse Proxy) ■■■■■■■■■■■■■■■■■■■■■■■■■■
nginx:
image: nginx:alpine
container_name: nginx_proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/[Link]:/etc/nginx/[Link]:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./certbot/conf:/etc/letsencrypt:ro
- ./certbot/www:/var/www/certbot:ro
depends_on:
- frontend
- backend
restart: unless-stopped
networks:
- app-network
# ■■ React Frontend ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: react_app
expose:
- "3000" # ■■■■ internal network-■ expose
environment:
- NODE_ENV=production
- REACT_APP_API_URL=[Link]
restart: unless-stopped
networks:
- app-network
# ■■ [Link] Backend API ■■■■■■■■■■■■■■■■■■■■■■■■■■■■
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: node_api
expose:
- "5000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:pass@postgres:5432/mydb
- JWT_SECRET=your-secret-key
- REDIS_URL=redis://redis:6379
depends_on:
- postgres
- redis
restart: unless-stopped
networks:
- app-network
# ■■ PostgreSQL Database ■■■■■■■■■■■■■■■■■■■■■■■■■■■■
postgres:
image: postgres:15-alpine
container_name: postgres_db
volumes:
- postgres_data:/var/lib/postgresql/data
- ./[Link]:/docker-entrypoint-initdb.d/[Link]
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=mydb
expose:
- "5432" # external access ■■■■!
restart: unless-stopped
networks:
- app-network
# ■■ Redis Cache ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
redis:
image: redis:7-alpine
container_name: redis_cache
expose:
- "6379"
volumes:
- redis_data:/data
restart: unless-stopped
networks:
- app-network
# ■■ Volumes ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
volumes:
postgres_data:
redis_data:
# ■■ Networks ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
networks:
app-network:
driver: bridge
nginx/conf.d/[Link]
# Docker Compose-■■ service name ■■■■■■■ ■■■ hostname ■■■■■■
upstream frontend {
server frontend:3000; # service name = hostname in Docker network
}
upstream backend {
server backend:5000;
}
server {
listen 80;
server_name [Link] [Link];
# Let's Encrypt ACME challenge
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# HTTP → HTTPS
location / {
return 301 [Link]
}
}
server {
listen 443 ssl http2;
server_name [Link] [Link];
ssl_certificate /etc/letsencrypt/live/[Link]/[Link];
ssl_certificate_key /etc/letsencrypt/live/[Link]/[Link];
client_max_body_size 20M;
# Frontend
location / {
proxy_pass [Link]
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# Backend API
location /api/ {
proxy_pass [Link]
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;
proxy_read_timeout 90;
}
}
Deploy Commands
# Start ■■■
docker-compose up -d
# Logs ■■■■
docker-compose logs -f nginx
# Rebuild ■ restart
docker-compose up -d --build
# Stop ■■■
docker-compose down
# Volumes ■■ ■■ ■■■■ ■■■■
docker-compose down -v
# Nginx config reload (container restart ■■■■■)
docker-compose exec nginx nginx -s reload
# Nginx config test
docker-compose exec nginx nginx -t
12. Security Best Practices
server {
listen 443 ssl http2;
server_name [Link];
# ■■ Version Hide ■■■ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
server_tokens off; # Nginx version hide
# ■■ Security Headers ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=()" always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-in
line';" always;
# ■■ Rate Limiting ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
# (http block-■ define ■■■)
# limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
# limit_conn_zone $binary_remote_addr zone=addr:10m;
location /api/ {
limit_req zone=api burst=20 nodelay;
limit_conn addr 10;
proxy_pass [Link]
}
# ■■ DDoS Protection ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
client_body_timeout 10s;
client_header_timeout 10s;
keepalive_timeout 5s 5s;
send_timeout 10s;
# ■■ Block Bad Bots ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
if ($http_user_agent ~* "sqlmap|nikto|masscan|nmap") {
return 403;
}
# ■■ Sensitive Files Block ■■■■■■■■■■■■■■■■■■■■■■■■■
location ~ /\.(git|env|htaccess|htpasswd) {
deny all;
return 404;
}
location ~ \.(sql|bak|old|backup)$ {
deny all;
}
# ■■ IP Whitelist (admin panel) ■■■■■■■■■■■■■■■■■■■■
location /admin {
allow [Link]/24;
allow [Link];
deny all;
proxy_pass [Link]
}
# ■■ Basic Auth ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
location /private {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass [Link]
}
}
13. Performance Tuning
# /etc/nginx/[Link]
worker_processes auto; # CPU cores = worker count
worker_rlimit_nofile 65535; # max open files
events {
worker_connections 65535;
use epoll;
multi_accept on;
}
http {
# ■■ Gzip Compression ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_min_length 1000;
gzip_types
text/plain text/css text/xml text/javascript
application/json application/javascript application/xml
image/svg+xml;
# ■■ Caching ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
proxy_cache_path /var/cache/nginx
levels=1:2
keys_zone=my_cache:10m
max_size=1g
inactive=60m
use_temp_path=off;
# ■■ Keepalive ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
keepalive_timeout 65;
keepalive_requests 1000;
# ■■ Buffers ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
client_body_buffer_size 128k;
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 16k;
# ■■ Sendfile (kernel-level, faster) ■■■■■■■■■■■■■■■
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# ■■ Open File Cache ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
14. Common Directives Cheat Sheet
Directive Context ■■■
listen server Port ■ IP listen ■■■
server_name server Domain name match ■■■
root http/server/location Document root directory
alias location Path replace ■■■
index http/server/location Default file
try_files location File ■■■■■ ■■ ■■■■ fallback
proxy_pass location Upstream server-■ forward
proxy_set_header location Upstream-■ header ■■■■■■
return server/location Redirect ■■ response
rewrite server/location URL rewrite ■■■
location server URL pattern match
upstream http Backend server group
add_header http/server/location Response header ■■■ ■■■
deny/allow http/server/location IP access control
limit_req location Request rate limit
gzip http/server/location Compression ■■■■ ■■■
ssl_certificate server SSL cert path
expires http/server/location Cache expiry time
client_max_body_size http/server/location Max upload size
error_page http/server/location Custom error pages
include any ■■■■ config file include
15. Troubleshooting
Common Errors ■ Solutions
Error ■■■■ Solution
nginx: [emerg] bind() to [Link]:80
Port 80
failed
already in use sudo fuser -k 80/tcp ■■■■ ■■■■ service ■■■■ ■■■
502 Bad Gateway Backend ■■■■ ■■ Backend service ■■■■ ■■■ ■■■■ ■■■■
504 Gateway Timeout Backend respond ■■■■ ■■ proxy_read_timeout ■■■■■■
403 Forbidden Permission ■■■■■■ File/folder permission ■ nginx user ■■■ ■■■
404 Not Found File ■■■ ■■ root ■■■ root path ■ try_files ■■■ ■■■
Upload size ■■■■
413 Request Entity Too Large client_max_body_size ■■■■■■
Debug Commands
# Config test
sudo nginx -t
# Error log ■■■■ (live)
sudo tail -f /var/log/nginx/[Link]
# Access log ■■■■ (live)
sudo tail -f /var/log/nginx/[Link]
# ■■■ port ■■ use ■■■■
sudo ss -tlnp | grep :80
sudo lsof -i :80
# Nginx process ■■■■
ps aux | grep nginx
# Docker container-■■ log
docker logs -f nginx_container
# Nginx reload without restart
sudo nginx -s reload
# Permission fix
sudo chown -R www-data:www-data /var/www/mysite
sudo chmod -R 755 /var/www/mysite
■ Nginx ■■■■■ ■■■■■■■ management ■■■■ ■■■ ■■■■ ■■ guide-■■ ■■ config
■■■■ try ■■■ – practice-■ best teacher!