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)