Nginx – High Performance Web Server and Reverse Proxy

4.9 Stars
Version 1.26
1 MB

Complete Guide to Nginx: Modern Web Server Excellence

Nginx (pronounced “engine-x”) has become the web server of choice for high-traffic websites, powering over 30% of the internet’s busiest sites. Originally created to solve the C10K problem (handling 10,000 concurrent connections), Nginx uses an asynchronous, event-driven architecture that efficiently handles massive concurrent loads while consuming minimal memory. Beyond serving static content, Nginx excels as a reverse proxy, load balancer, and HTTP cache.

Its lightweight footprint and exceptional performance make Nginx ideal for everything from small personal sites to enterprise infrastructure. Companies like Netflix, Dropbox, and WordPress.com rely on Nginx to deliver content to millions of users.

Installation

# Ubuntu/Debian
sudo apt update
sudo apt install nginx

# Start and enable
sudo systemctl start nginx
sudo systemctl enable nginx

# Fedora
sudo dnf install nginx
sudo systemctl start nginx

# Arch Linux
sudo pacman -S nginx
sudo systemctl start nginx

# macOS
brew install nginx
brew services start nginx

# Docker
docker run -d --name nginx -p 80:80 nginx

# Verify installation
nginx -v
curl http://localhost

# Test configuration
sudo nginx -t

# Reload configuration
sudo nginx -s reload

Configuration Structure

# Main configuration file
/etc/nginx/nginx.conf

# Site configurations
/etc/nginx/sites-available/
/etc/nginx/sites-enabled/

# Or conf.d approach
/etc/nginx/conf.d/

# Main config structure
user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 1024;
    multi_accept on;
}

http {
    # Global HTTP settings
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    # Logging
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    
    # Performance
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    
    # Gzip compression
    gzip on;
    gzip_types text/plain application/json application/javascript text/css;
    
    # Include site configs
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Server Blocks (Virtual Hosts)

# Basic server block
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.html index.htm;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

# Enable site
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

# Default server
server {
    listen 80 default_server;
    server_name _;
    return 444;  # Close connection
}

# Multiple domains
server {
    listen 80;
    server_name domain1.com domain2.com *.example.com;
    # ...
}

# IP-based
server {
    listen 192.168.1.100:80;
    # ...
}

Location Blocks

# Exact match
location = /exact {
    # Only matches /exact
}

# Prefix match
location /images/ {
    # Matches /images/*
}

# Regular expression (case sensitive)
location ~ \.php$ {
    # Matches .php files
}

# Regular expression (case insensitive)
location ~* \.(jpg|jpeg|png|gif)$ {
    # Matches image files
}

# Preferential prefix
location ^~ /static/ {
    # Takes precedence over regex
}

# Priority order:
# 1. Exact (=)
# 2. Preferential prefix (^~)
# 3. Regex (~ or ~*)
# 4. Prefix (longest match)

# Nested locations
location /api/ {
    location /api/v1/ {
        # More specific
    }
}

Reverse Proxy

# Basic reverse proxy
server {
    listen 80;
    server_name example.com;
    
    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}

# WebSocket support
location /ws/ {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

# Timeout settings
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# Buffering
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;

Load Balancing

# Upstream definition
upstream backend {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    server 192.168.1.12:8080;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

# Load balancing methods
upstream backend {
    # Round robin (default)
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
    
    # Weighted
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 weight=1;
    
    # Least connections
    least_conn;
    
    # IP hash (sticky sessions)
    ip_hash;
}

# Server options
upstream backend {
    server 192.168.1.10:8080 weight=3;
    server 192.168.1.11:8080 backup;      # Only if others fail
    server 192.168.1.12:8080 down;        # Marked as down
    server 192.168.1.13:8080 max_fails=3 fail_timeout=30s;
}

# Health checks (commercial)
upstream backend {
    server 192.168.1.10:8080;
    health_check interval=5s;
}

SSL/TLS Configuration

# HTTPS server
server {
    listen 443 ssl http2;
    server_name example.com;
    
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
    
    # Modern configuration
    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 caching
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;
    
    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
}

# HTTP to HTTPS redirect
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

# Let's Encrypt with Certbot
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com

Caching

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

# Proxy cache
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g;

server {
    location / {
        proxy_cache my_cache;
        proxy_cache_valid 200 1h;
        proxy_cache_valid 404 1m;
        proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
        proxy_pass http://backend;
        
        add_header X-Cache-Status $upstream_cache_status;
    }
}

# FastCGI cache
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=php_cache:10m;

location ~ \.php$ {
    fastcgi_cache php_cache;
    fastcgi_cache_valid 200 60m;
    fastcgi_pass unix:/var/run/php/php-fpm.sock;
}

Security

# 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 Content-Security-Policy "default-src 'self'" always;

# Hide Nginx version
server_tokens off;

# Rate limiting
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

server {
    location /api/ {
        limit_req zone=one burst=20 nodelay;
    }
}

# Connection limiting
limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
    limit_conn addr 10;
}

# Basic authentication
location /admin/ {
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

# IP restriction
location /internal/ {
    allow 192.168.1.0/24;
    deny all;
}

PHP-FPM Configuration

# PHP processing
server {
    root /var/www/html;
    index index.php index.html;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_index index.php;
    }
    
    # Deny access to .htaccess
    location ~ /\.ht {
        deny all;
    }
}

Logging

# Custom log format
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';

log_format json escape=json '{'
    '"time":"$time_iso8601",'
    '"remote_addr":"$remote_addr",'
    '"request":"$request",'
    '"status":$status,'
    '"body_bytes_sent":$body_bytes_sent'
'}';

# Per-server logging
server {
    access_log /var/log/nginx/example.access.log main;
    error_log /var/log/nginx/example.error.log warn;
}

# Conditional logging
map $status $loggable {
    ~^[23] 0;
    default 1;
}

access_log /var/log/nginx/access.log combined if=$loggable;

Conclusion

Nginx has earned its position as a cornerstone of modern web infrastructure through exceptional performance, flexibility, and reliability. Whether serving static files, proxying application servers, or balancing load across clusters, Nginx handles these tasks efficiently while consuming minimal resources. Its straightforward configuration syntax and extensive documentation make it accessible to administrators at all levels while providing the power needed for the most demanding deployments.

Developer: NGINX Inc

Download Options

Download Nginx – High Performance Web Server and Reverse Proxy

Version 1.26

File Size: 1 MB

Download Now
Safe & Secure

Verified and scanned for viruses

Regular Updates

Always get the latest version

24/7 Support

Help available when you need it