Nginx – High Performance Web Server and Reverse Proxy
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.
Download Options
Download Nginx – High Performance Web Server and Reverse Proxy
Version 1.26
File Size: 1 MB
Download NowSafe & Secure
Verified and scanned for viruses
Regular Updates
Always get the latest version
24/7 Support
Help available when you need it