Introduction
Nginx (pronounced "engine-x") is a high-performance web server, reverse proxy, and load balancer. Originally created by Igor Sysoev in 2004, nginx has become one of the most popular web servers in the world due to its efficiency, stability, and low resource consumption.
Key Features
- High Performance: Can handle thousands of concurrent connections
- Low Memory Usage: Efficient resource utilization
- Reverse Proxy: Route requests to backend servers
- Load Balancing: Distribute traffic across multiple servers
- SSL/TLS Termination: Handle encrypted connections
- Static File Serving: Excellent for serving static content
- HTTP Caching: Built-in caching capabilities
Installation
Ubuntu/Debian
sudo apt update sudo apt install nginx
CentOS/RHEL/Fedora
# CentOS/RHEL sudo yum install nginx # Fedora sudo dnf install nginx
macOS (using Homebrew)
brew install nginx
Starting and Enabling Nginx
# Start nginx sudo systemctl start nginx # Enable nginx to start on boot sudo systemctl enable nginx # Check status sudo systemctl status nginx
Basic Configuration
Configuration File Structure
Nginx configuration files are typically located at:
- Main config:
/etc/nginx/nginx.conf
- Site configs:
/etc/nginx/sites-available/
and/etc/nginx/sites-enabled/
- Additional configs:
/etc/nginx/conf.d/
Basic nginx.conf Structure
# Main context user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Events context events { worker_connections 1024; use epoll; } # HTTP context http { # MIME types and basic settings include /etc/nginx/mime.types; default_type application/octet-stream; # Logging access_log /var/log/nginx/access.log; # Performance settings sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; # Include additional configurations include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }
Common Use Cases
1. Static Web Server
Create a configuration file for serving static content:
server { listen 80; server_name example.com www.example.com; root /var/www/html; index index.html index.htm; location / { try_files $uri $uri/ =404; } # Optimize static file serving location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; } }
2. Reverse Proxy
Route requests to a backend application server:
server { listen 80; server_name api.example.com; location / { proxy_pass http://localhost:3000; 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; } }
3. Load Balancer
Distribute traffic across multiple backend servers:
upstream backend { server 192.168.1.10:8080; server 192.168.1.11:8080; server 192.168.1.12:8080; } server { listen 80; server_name app.example.com; location / { proxy_pass http://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; } }
4. SSL/HTTPS Configuration
Configure SSL termination with Let's Encrypt certificates:
server { listen 80; server_name example.com www.example.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name example.com www.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # Modern SSL configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; root /var/www/html; index index.html; location / { try_files $uri $uri/ =404; } }
Advanced Configurations
Rate Limiting
Protect your server from abuse:
http { limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; server { listen 80; server_name api.example.com; location /api/ { limit_req zone=api burst=20 nodelay; proxy_pass http://backend; } } }
Caching
Implement HTTP caching:
http { proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; server { listen 80; server_name example.com; location / { proxy_cache my_cache; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_pass http://backend; } } }
Compression
Enable gzip compression:
http { gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json; }
Security Best Practices
Hide Nginx Version
http { server_tokens off; }
Security Headers
server { add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; }
IP Restriction
location /admin { allow 192.168.1.0/24; allow 10.0.0.0/8; deny all; }
Common Commands
Testing Configuration
# Test configuration syntax sudo nginx -t # Test configuration and show details sudo nginx -T
Reloading Configuration
# Reload configuration without downtime sudo systemctl reload nginx # Or using nginx command sudo nginx -s reload
Managing Service
# Start nginx sudo systemctl start nginx # Stop nginx sudo systemctl stop nginx # Restart nginx sudo systemctl restart nginx # Check status sudo systemctl status nginx
Troubleshooting
Check Logs
# Error logs sudo tail -f /var/log/nginx/error.log # Access logs sudo tail -f /var/log/nginx/access.log
Common Issues
Permission Denied (403 Forbidden)
- Check file permissions:
chmod 644 files
andchmod 755 directories
- Verify nginx user has access to the document root
- Check SELinux settings if applicable
Connection Refused
- Verify nginx is running:
systemctl status nginx
- Check if the port is being used:
netstat -tlnp | grep :80
- Review firewall settings
Configuration Errors
- Always test configuration before reloading:
nginx -t
- Check for syntax errors in configuration files
- Verify file paths exist and are accessible
Performance Tuning
Worker Processes and Connections
# Set to number of CPU cores worker_processes auto; events { # Increase for high-traffic sites worker_connections 2048; use epoll; multi_accept on; }
Buffer Sizes
http { client_body_buffer_size 10K; client_header_buffer_size 1k; client_max_body_size 8m; large_client_header_buffers 2 1k; }
Timeouts
http { client_body_timeout 12; client_header_timeout 12; keepalive_timeout 15; send_timeout 10; }
Monitoring
Basic Monitoring with Stub Status
server { listen 80; server_name localhost; location /nginx_status { stub_status on; allow 127.0.0.1; deny all; } }
Log Analysis
Use tools like GoAccess for log analysis:
goaccess /var/log/nginx/access.log --log-format=COMBINED
Conclusion
Nginx is a powerful and flexible web server that can handle various scenarios from simple static file serving to complex load balancing setups. The key to mastering nginx is understanding its configuration structure and gradually building up complexity as needed.
Start with basic configurations and progressively add features like SSL, caching, and security headers. Always test your configurations before applying them to production, and monitor your server's performance to ensure optimal operation.
For production deployments, consider implementing proper monitoring, logging, and backup strategies to maintain a robust web infrastructure.
Feel free to share your thoughts and criticize this article, if you find any inconvenience! Cheers
Top comments (0)