# Deep Dive on NGINX Configuration Blocks

NGINX is a highly configurable web server and reverse proxy, and its power comes from its **configuration blocks**. These blocks define how requests are processed, connections are managed, and traffic is handled in various scenarios.

Here is the list of the configuration blocks :

* **Main (Global) Context**
* **Events Block**
* **HTTP Block**
* **Server Block**
* **Location Block**
* **Upstream Block**
* **Mail Block (for email proxying)**
* **Stream Block (for TCP/UDP load balancing)**

***

### **1. Main (Global) Context**

The **global** or **main context** sets global directives for the entire NGINX process, including worker processes, error logging, and module loading. It is placed outside any specific block.

#### **Key Directives in Main Context**

| Directive          | Purpose                                                                       |
| ------------------ | ----------------------------------------------------------------------------- |
| `worker_processes` | Defines the number of worker processes (usually set to `auto` in production). |
| `error_log`        | Specifies the location and level of error logs.                               |
| `pid`              | Defines the file where NGINX stores its process ID.                           |
| `include`          | Allows importing additional configuration files.                              |

#### **Example:**

```nginx
worker_processes auto;         # Auto-detects CPU cores for optimal performance
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
```

#### **Production Tip:**

Set `worker_processes auto;` to utilize all available CPU cores.

***

### **2. Events Block**

The **events block** configures how NGINX handles client connections.

#### **Key Directives in Events Block**

| Directive            | Purpose                                                      |
| -------------------- | ------------------------------------------------------------ |
| `worker_connections` | Defines the max simultaneous connections per worker process. |
| `multi_accept`       | Allows a worker to accept multiple new connections at once.  |
| `use`                | Specifies the event-driven model (e.g., `epoll` for Linux).  |

#### **Final Example:**

```nginx
events {
    worker_connections 1024;   # Handles 1024 connections per worker
    multi_accept on;           # Accept multiple connections at once
    use epoll;                 # Use efficient event model (Linux)
}
```

#### **Production Tip:**

For high-traffic applications, increase `worker_connections` based on server resources.

***

### **3. HTTP Block**

The **HTTP block** is where web server configurations, caching, compression, and proxy settings are defined.

#### **Key Directives in HTTP Block**

| Directive               | Purpose                                                                                                                                                     |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sendfile`              | Enables optimized file transfers.                                                                                                                           |
| `tcp_nopush`            | Reduces TCP overhead.                                                                                                                                       |
| `keepalive_timeout`     | Defines how long persistent connections stay open.                                                                                                          |
| `resolver`              | Specifies DNS resolvers for dynamic upstream handling. especially important when using domain names in upstream blocks. Here it will work as global for all |
| `log_format`            | Customizes the access log format.                                                                                                                           |
| include                 | Include MIME types and other HTTP-level configurations.                                                                                                     |
| client\_max\_body\_size | Defines the maximum allowed size of the client request body.                                                                                                |

#### **Example:**

```nginx
http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    tcp_nopush      on;
    keepalive_timeout 65;
    
    client_max_body_size 16M;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" "$http_user_agent"';

    access_log /var/log/nginx/access.log main;

    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
}
```

#### **Production Tip:**

Enable Gzip compression (`gzip on;`) to improve page load times.

***

### **4. Server Block**

The **server block** defines individual virtual hosts that listen for incoming requests.

#### **Key Directives in Server Block**

| Directive     | Purpose                                                                                                                                                               |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `listen`      | Defines the port (e.g., `80` for HTTP, `443` for HTTPS).                                                                                                              |
| `server_name` | Specifies domains for this server block.                                                                                                                              |
| `root`        | Sets the root directory for static files.                                                                                                                             |
| `index`       | Defines the default files to serve.                                                                                                                                   |
| error\_page   | Customize the error responses.                                                                                                                                        |
| resolver      | Specifies DNS resolvers for dynamic upstream handling. especially important when using domain names in upstream blocks. Here it will work as server level not global. |

#### **Final Example:**

```nginx
server {
    listen 80;
    server_name example.com www.example.com;

    root /var/www/html;
    index index.html index.htm;
    
    resolver 10.0.0.2 ipv6=off valid=300s;
    resolver_timeout 5s;

    error_page 404 /404.html;
}
```

#### **Production Tip:**

Use separate `server {}` blocks for HTTP and HTTPS.

***

### **5. Location Block**

The **location block** defines how specific request paths are handled.

#### **Key Directives in Location Block**

| Directive          | Purpose                                    |
| ------------------ | ------------------------------------------ |
| `location`         | Defines URL patterns for request handling. |
| `proxy_pass`       | Forwards requests to an upstream server.   |
| proxy\_set\_header | To farward header to upstream server       |
| `rewrite`          | Modifies request URIs dynamically.         |

#### **Example:**

```nginx
location /api/ {
    proxy_pass http://backend_servers;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    
    rewrite ^/old/(.*)$ /new/$1 permanent;
}
```

#### **Production Tip:**

Use `try_files $uri $uri/ =404;` for serving static content.

***

### **6. Upstream Block**

The **upstream block** defines backend servers for load balancing.

#### **Key Directives in Upstream Block**

| Directive | Purpose                          |
| --------- | -------------------------------- |
| `server`  | Specifies backend servers.       |
| `weight`  | Assigns load balancing priority. |

#### **Final Example:**

```nginx
upstream backend_servers {
    server backend1.example.com weight=2;
    server backend2.example.com;
}
```

#### **Production Tip:**

Use `ip_hash;` for session persistence.

***

### **7. Mail Block**

The **mail block** enables NGINX to act as an email proxy.

#### **Key Directives in Mail Block**

| Directive  | Purpose                                       |
| ---------- | --------------------------------------------- |
| `server`   | Defines mail servers.                         |
| `protocol` | Specifies email protocols (IMAP, POP3, SMTP). |

#### **Final Example:**

```nginx
mail {
    server {
        listen 143;
        protocol imap;
        server_name mail.example.com;
    }
}
```

#### **Production Tip:**

Secure email connections using SSL.

***

### **8. Stream Block**

The **stream block** allows NGINX to handle TCP/UDP traffic (e.g., databases).

#### **Key Directives in Stream Block**

| Directive    | Purpose                   |
| ------------ | ------------------------- |
| `proxy_pass` | Forwards TCP/UDP traffic. |
| `upstream`   | Defines backend servers.  |

#### **Final Example:**

```nginx
stream {
    upstream db_servers {
        server db1.example.com:3306;
        server db2.example.com:3306;
    }

    server {
        listen 3306;
        proxy_pass db_servers;
    }
}
```

#### **Production Tip:**

For database connections, enable `proxy_timeout` to prevent idle disconnections.

### Final Configuration Example

{% code fullWidth="true" %}

```nginx
###############################################################################
# Global (Main) Context
###############################################################################
# These settings apply to the entire NGINX process.
worker_processes auto;                        # Auto-detects CPU cores for optimal performance.
error_log /var/log/nginx/error.log warn;        # Log errors with a level of 'warn' for production.
pid /var/run/nginx.pid;                         # Store the master process PID.

# Include additional configuration files (e.g., dynamic modules or custom settings).
include /etc/nginx/modules-enabled/*.conf;

###############################################################################
# Events Block
###############################################################################
# The events block configures how NGINX handles connections.
events {
    worker_connections 1024;                    # Maximum simultaneous connections per worker.
    multi_accept on;                            # Accept all new connections at once.
    use epoll;                                  # Use the epoll event model (recommended for Linux).
}

###############################################################################
# HTTP Block
###############################################################################
# This block manages web (HTTP/HTTPS) traffic.
http {
    # Include MIME types and set a default content type.
    include       mime.types;
    default_type  application/octet-stream;
    
    # File transfer and TCP optimizations.
    sendfile        on;
    tcp_nodelay     on;
    tcp_nopush      on;
    
    # Connection and request settings.
    keepalive_timeout 65;                       # Timeout for persistent connections.
    client_max_body_size 16M;                   # Maximum allowed size of client request bodies.
    
    # Logging configuration with custom variables.
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" "$http_user_agent" '
                    'Request URI: $uri, Query: $query_string';
    access_log /var/log/nginx/access.log main;
    
    # Resolver settings to control DNS resolution.
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    
    ###############################################################################
    # Upstream Block
    ###############################################################################
    # Defines a group of backend servers for load balancing.
    upstream backend_servers {
        server backend1.example.com weight=2;   # Weighted balancing (backend1 gets double traffic).
        server backend2.example.com;
    }
    
    ###############################################################################
    # Server Block (HTTP)
    ###############################################################################
    # Defines virtual hosts for handling specific domain requests.
    server {
        listen 80 default_server;               # Listen on port 80 for HTTP traffic.
        server_name example.com www.example.com;  # Domain names this server responds to.
        
        root /var/www/example;                  # Root directory for static files.
        index index.html index.htm;             # Default files to serve.
        
        # Custom error page configuration.
        error_page 404 /404.html;
        location = /404.html {
            internal;                         # Ensure direct access is not allowed.
        }
        
        ###############################################################################
        # Location Blocks within Server
        ###############################################################################
        
        # Location block for static content.
        location /static/ {
            try_files $uri $uri/ =404;         # Check file existence, return 404 if not found.
        }
        
        # Location block for PHP processing using FastCGI.
        location ~ \.php$ {
            fastcgi_pass unix:/run/php/php7.4-fpm.sock;
            fastcgi_index index.php;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
        
        # Location block for API proxying to upstream backend servers.
        location /api/ {
            proxy_pass http://backend_servers;
            proxy_set_header Host $host;        # Forward the original host header.
            proxy_set_header X-Real-IP $remote_addr;  # Forward client’s IP address.
            proxy_redirect off;                 # Disable automatic redirection.
        }
        
        # Example of URI rewrite for permanent redirection.
        location /old/ {
            rewrite ^/old/(.*)$ /new/$1 permanent;
        }
    }
    
    ###############################################################################
    # Additional Server Block (HTTPS Example)
    ###############################################################################
    # Demonstrates how to configure a secure server with SSL/TLS.
    server {
        listen 443 ssl;
        server_name secure.example.com;
        
        root /var/www/secure;
        index index.html index.htm;
        
        ssl_certificate /etc/nginx/ssl/secure.example.com.crt;
        ssl_certificate_key /etc/nginx/ssl/secure.example.com.key;
        
        # Example of HTTP basic authentication for sensitive areas.
        location /secure/ {
            auth_basic "Restricted Content";
            auth_basic_user_file /etc/nginx/.htpasswd;
        }
    }
}

###############################################################################
# Optional Mail Block
###############################################################################
# For email proxying (IMAP, POP3, SMTP). Uncomment and configure as needed.
# mail {
#     server {
#         listen     143;
#         protocol   imap;
#         server_name mail.example.com;
#         # Additional mail-specific directives go here.
#     }
# }

###############################################################################
# Optional Stream Block
###############################################################################
# For TCP/UDP load balancing (e.g., databases, other non-HTTP services).
stream {
    upstream db_servers {
        server db1.example.com:3306;
        server db2.example.com:3306;
    }
    
    server {
        listen 3306;
        proxy_pass db_servers;
    }
}

```

{% endcode %}

***

### **Conclusion**

Each NGINX configuration block plays a crucial role in handling traffic efficiently. Understanding these blocks and their **production best practices** ensures a **secure, scalable, and high-performance** setup.

By applying these blocks correctly, you can optimize **static content delivery, API routing, load balancing, email proxying, and database handling**, making NGINX a powerful tool for any production environment.
