DEV Community

Cover image for Complete Guide to Using Nginx
Maksym
Maksym

Posted on

Complete Guide to Using Nginx

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
Enter fullscreen mode Exit fullscreen mode

CentOS/RHEL/Fedora

# CentOS/RHEL
sudo yum install nginx

# Fedora
sudo dnf install nginx
Enter fullscreen mode Exit fullscreen mode

macOS (using Homebrew)

brew install nginx
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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/*;
}
Enter fullscreen mode Exit fullscreen mode

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";
    }
}
Enter fullscreen mode Exit fullscreen mode

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

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;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

Security Best Practices

Hide Nginx Version

http {
    server_tokens off;
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

IP Restriction

location /admin {
    allow 192.168.1.0/24;
    allow 10.0.0.0/8;
    deny all;
}
Enter fullscreen mode Exit fullscreen mode

Common Commands

Testing Configuration

# Test configuration syntax
sudo nginx -t

# Test configuration and show details
sudo nginx -T
Enter fullscreen mode Exit fullscreen mode

Reloading Configuration

# Reload configuration without downtime
sudo systemctl reload nginx

# Or using nginx command
sudo nginx -s reload
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Troubleshooting

Check Logs

# Error logs
sudo tail -f /var/log/nginx/error.log

# Access logs
sudo tail -f /var/log/nginx/access.log
Enter fullscreen mode Exit fullscreen mode

Common Issues

Permission Denied (403 Forbidden)

  • Check file permissions: chmod 644 files and chmod 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;
}
Enter fullscreen mode Exit fullscreen mode

Buffer Sizes

http {
    client_body_buffer_size 10K;
    client_header_buffer_size 1k;
    client_max_body_size 8m;
    large_client_header_buffers 2 1k;
}
Enter fullscreen mode Exit fullscreen mode

Timeouts

http {
    client_body_timeout 12;
    client_header_timeout 12;
    keepalive_timeout 15;
    send_timeout 10;
}
Enter fullscreen mode Exit fullscreen mode

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

Log Analysis

Use tools like GoAccess for log analysis:

goaccess /var/log/nginx/access.log --log-format=COMBINED
Enter fullscreen mode Exit fullscreen mode

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)