nginx Configuration Best Practices
nginxweb serverreverse proxyload balancerconfiguration
Description
This rule provides a comprehensive guide to nginx configuration best practices, covering code organization, common patterns, performance, security, testing, pitfalls, and tooling.
Globs
**/nginx.conf
---
description: This rule provides a comprehensive guide to nginx configuration best practices, covering code organization, common patterns, performance, security, testing, pitfalls, and tooling.
globs: **/nginx.conf
---
# nginx Configuration Best Practices
This document outlines best practices for configuring nginx as a web server, reverse proxy, and load balancer. Adhering to these guidelines promotes maintainability, security, and performance.
## 1. Code Organization and Structure
### 1.1 Directory Structure
Maintain a well-organized directory structure to manage configuration files efficiently.
/etc/nginx/
├── nginx.conf # Main nginx configuration file
├── conf.d/ # Site-specific configurations (symlinks preferred)
│ ├── default.conf # Default configuration
│ ├── example.com.conf# Site-specific configuration
│ └── ...
├── snippets/ # Reusable configuration snippets
│ ├── ssl-params.conf # SSL parameters
│ ├── proxy-params.conf # Reverse proxy parameters
│ └── ...
└── modules-enabled/ # Enabled modules (usually managed by package manager)
**Explanation:**
* `/etc/nginx/nginx.conf`: The main configuration file that includes other configurations.
* `/etc/nginx/conf.d/`: Contains site-specific configurations. Symlinking from `/etc/nginx/sites-available/` to `/etc/nginx/sites-enabled/` is a common, more manageable pattern.
* `/etc/nginx/snippets/`: Stores reusable configuration snippets, promoting modularity and reducing duplication.
### 1.2 File Naming Conventions
Adopt consistent file naming conventions for clarity.
* Site-specific configurations: `domain.com.conf` or `application-name.conf`.
* Snippets: `description.conf` (e.g., `ssl-params.conf`, `proxy-params.conf`).
### 1.3 Modular Configuration
Break down complex configurations into smaller, reusable modules (snippets).
**Example: `snippets/ssl-params.conf`**
nginx
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_ecdh_curve prime256v1;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
**Usage in site configuration:**
nginx
server {
listen 443 ssl;
server_name example.com;
include snippets/ssl-params.conf;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
location / {
# ...
}
}
### 1.4 Component Architecture
Design your nginx configurations with a clear separation of concerns:
* **Global Settings**: Core directives in `nginx.conf` affecting all virtual hosts.
* **Virtual Host Configuration**: Separate files for each site/application in `conf.d/`.
* **Reusable Blocks**: Snippets for common settings like SSL, reverse proxy configurations, or access control.
### 1.5 Code Splitting
For large and complex configurations, split files by functionality (e.g., routing rules, security policies, caching configurations). Use `include` directives to assemble the complete configuration.
## 2. Common Patterns and Anti-patterns
### 2.1 Design Patterns
* **Reverse Proxy**: Forward requests to backend servers. Useful for load balancing, caching, and security.
* **Load Balancer**: Distribute traffic across multiple backend servers for high availability and scalability. Use `upstream` blocks.
* **Static Content Server**: Efficiently serve static files like images, CSS, and JavaScript.
* **Cache**: Reduce latency and server load by caching frequently accessed content.
### 2.2 Recommended Approaches for Common Tasks
* **Serving Static Content:**
nginx
location /static/ {
alias /var/www/example.com/static/;
expires 30d;
access_log off;
}
* **Reverse Proxy to a Backend Server:**
nginx
location / {
proxy_pass http://backend_server;
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;
}
upstream backend_server {
server backend1.example.com;
server backend2.example.com;
}
* **Implementing Basic Authentication:**
nginx
location /protected/ {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
### 2.3 Anti-patterns and Code Smells
* **Large, Monolithic Configuration Files**: Difficult to manage and debug. Break them into smaller, modular files using `include`.
* **Duplicated Configuration Blocks**: Create snippets to reuse common configurations.
* **Using `if` Statements Excessively**: `if` statements can have performance implications. Prefer using `try_files` or other more efficient directives.
* **Insecure Configuration**: Exposing sensitive information, using weak ciphers, or not implementing proper access controls.
* **Ignoring Error Logs**: Neglecting to monitor and analyze error logs can lead to undetected issues.
### 2.4 State Management
Nginx itself is generally stateless. State management is typically handled by backend applications. However, Nginx Plus offers features like session persistence (sticky sessions) for load balancing.
* **Session Persistence (Nginx Plus):**
nginx
upstream backend {
server backend1.example.com;
server backend2.example.com;
sticky cookie srv_id expires=1h;
}
### 2.5 Error Handling
* **Custom Error Pages**: Configure custom error pages for a better user experience.
nginx
error_page 404 /404.html;
location = /404.html {
root /var/www/example.com/html;
internal;
}
* **Logging**: Use comprehensive logging to capture errors and warnings for troubleshooting.
* **Retry Logic**: Implement retry logic in your application or use Nginx's `proxy_next_upstream` directive to retry failed requests on different backend servers.
## 3. Performance Considerations
### 3.1 Optimization Techniques
* **Enable Gzip Compression**: Compress text-based responses to reduce bandwidth usage.
nginx
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
* **Enable Caching**: Cache static content and dynamic responses to reduce server load and improve response times. Use `proxy_cache_path` and `proxy_cache` directives.
nginx
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off;
server {
location / {
proxy_pass http://backend_server;
proxy_cache my_cache;
proxy_cache_valid 200 302 1h;
proxy_cache_valid 404 10m;
proxy_cache_use_stale error timeout updating invalid_header http_500 http_502 http_503 http_504;
add_header X-Cache-Status $upstream_cache_status;
}
}
* **Tune Worker Processes and Connections**: Adjust `worker_processes` and `worker_connections` based on your server's resources.
nginx
worker_processes auto;
events {
worker_connections 1024;
}
* **HTTP/2 or HTTP/3**: Enable HTTP/2 or HTTP/3 for improved performance.
* **Keep-Alive Connections**: Enable keep-alive connections to reduce latency by reusing existing connections.
nginx
keepalive_timeout 65;
### 3.2 Memory Management
* **Optimize Buffer Sizes**: Tune buffer sizes (e.g., `proxy_buffer_size`, `proxy_buffers`) to match your application's needs and avoid memory fragmentation.
* **Monitor Memory Usage**: Use tools like `top` or `htop` to monitor nginx's memory usage and identify potential memory leaks.
### 3.3 Rendering Optimization (If applicable)
Nginx primarily serves content; rendering optimization is typically handled by the backend application.
* **Content Delivery Network (CDN)**: Offload static content delivery to a CDN.
### 3.4 Bundle Size Optimization (If applicable)
This primarily applies to serving static assets.
* **Minify and Compress**: Minify and compress CSS and JavaScript files before serving them.
* **Use Brotli**: Consider using Brotli compression, which offers better compression ratios than Gzip.
### 3.5 Lazy Loading (If applicable)
This is typically implemented at the application level.
## 4. Security Best Practices
### 4.1 Common Vulnerabilities and Prevention
* **SQL Injection**: Prevent SQL injection by validating and sanitizing user inputs at the application level.
* **Cross-Site Scripting (XSS)**: Implement proper output encoding and use HTTP headers like `X-XSS-Protection` and `Content-Security-Policy`.
nginx
add_header X-XSS-Protection "1; mode=block";
add_header Content-Security-Policy "default-src 'self'";
* **Clickjacking**: Prevent clickjacking by setting the `X-Frame-Options` header.
nginx
add_header X-Frame-Options "SAMEORIGIN";
* **Buffer Overflow**: Keep Nginx up to date to patch vulnerabilities related to buffer overflows.
* **Denial of Service (DoS)**: Implement rate limiting to prevent DoS attacks.
nginx
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s;
location / {
limit_req zone=mylimit burst=5 nodelay;
# ...
}
### 4.2 Input Validation
* **Validate User Inputs**: Validate all user inputs at the application level to prevent malicious data from reaching backend servers.
* **Limit Request Size**: Limit the size of incoming requests to prevent buffer overflows and DoS attacks.
nginx
client_max_body_size 2m;
### 4.3 Authentication and Authorization
* **Basic Authentication**: Use basic authentication for simple access control. However, it's not secure over HTTP; always use HTTPS.
* **JWT (JSON Web Tokens)**: Implement JWT-based authentication for APIs.
* **OAuth 2.0**: Use OAuth 2.0 for delegated authorization.
* **Access Control Lists (ACLs)**: Use ACLs to control access to specific resources based on IP addresses or other criteria.
nginx
allow 192.168.1.0/24;
deny all;
### 4.4 Data Protection
* **HTTPS**: Use HTTPS to encrypt all traffic between clients and the server. Obtain and configure SSL/TLS certificates.
* **Secure Storage**: Store sensitive data (e.g., passwords, API keys) securely using encryption and access controls.
### 4.5 Secure API Communication
* **API Keys**: Require API keys for all API requests.
* **Rate Limiting**: Implement rate limiting to prevent abuse and DoS attacks.
* **Input Validation**: Validate all API request parameters.
* **Output Encoding**: Encode API responses to prevent XSS attacks.
## 5. Testing Approaches
### 5.1 Unit Testing
Nginx configuration files are difficult to unit test directly. Unit testing is more relevant for custom Nginx modules written in C.
### 5.2 Integration Testing
* **Test Configuration Syntax**: Use `nginx -t` to test the syntax of your configuration files.
* **Test with Docker**: Use Docker containers to create isolated test environments.
* **Test with Real Traffic**: Use tools like `ab` (Apache Bench) or `wrk` to simulate real traffic and measure performance.
### 5.3 End-to-End Testing
Use tools like Selenium or Cypress to automate end-to-end tests of your application.
### 5.4 Test Organization
* **Separate Test Environment**: Create a separate test environment that mirrors your production environment.
* **Automated Testing**: Automate your testing process using CI/CD pipelines.
### 5.5 Mocking and Stubbing
* **Mock Backend Services**: Mock backend services to isolate your Nginx configuration and test different scenarios.
## 6. Common Pitfalls and Gotchas
### 6.1 Frequent Mistakes
* **Incorrect Syntax**: Nginx configuration syntax can be tricky. Always test your configuration files using `nginx -t`.
* **Missing Semicolons**: Forgetting semicolons at the end of directives.
* **Incorrect File Permissions**: Ensure that Nginx has the necessary permissions to read configuration files and access static content.
* **Not Reloading Configuration**: Forgetting to reload Nginx after making changes to the configuration files (e.g., `nginx -s reload`).
* **Using `if` Statements Inappropriately**: Overusing `if` can lead to unexpected behavior and performance issues. Prefer `try_files` or other alternatives.
### 6.2 Edge Cases
* **Handling Large Files**: Tune buffer sizes and timeouts when handling large file uploads or downloads.
* **WebSockets**: Configure Nginx to properly proxy WebSocket connections.
* **Long URIs**: Configure `client_header_buffer_size` and `large_client_header_buffers` to handle long URIs.
### 6.3 Version-Specific Issues
* **Check Release Notes**: Review the release notes for each Nginx version to identify any breaking changes or known issues.
* **Test Upgrades**: Test Nginx upgrades in a staging environment before deploying to production.
### 6.4 Compatibility Concerns
* **Backend Application Compatibility**: Ensure that your Nginx configuration is compatible with the backend applications you are using.
* **TLS Versions and Ciphers**: Choose TLS versions and ciphers that are compatible with your clients and backend servers.
### 6.5 Debugging Strategies
* **Error Logs**: Check Nginx error logs (`/var/log/nginx/error.log`) for errors and warnings.
* **Access Logs**: Analyze Nginx access logs (`/var/log/nginx/access.log`) to understand traffic patterns and identify potential issues.
* **`nginx -t`**: Use `nginx -t` to test the syntax of your configuration files.
* **Verbose Logging**: Enable verbose logging to capture more detailed information about requests and responses.
* **tcpdump/Wireshark**: Use `tcpdump` or Wireshark to capture and analyze network traffic.
## 7. Tooling and Environment
### 7.1 Recommended Development Tools
* **Text Editor**: Use a text editor with syntax highlighting and autocompletion for Nginx configuration files (e.g., VS Code with Nginx configuration extension).
* **Command-Line Tools**: Use command-line tools like `nginx`, `curl`, `ab`, and `tcpdump` for testing and debugging.
* **Docker**: Use Docker for creating isolated test environments.
### 7.2 Build Configuration
* **Version Control**: Store your Nginx configuration files in a version control system (e.g., Git).
* **Configuration Management**: Use configuration management tools like Ansible or Chef to automate the deployment and management of your Nginx configuration.
### 7.3 Linting and Formatting
* **Nginx Linter**: Use an Nginx linter to check your configuration files for syntax errors and best practices violations (e.g., `nginx -t`).
* **Code Formatting**: Use a code formatter to ensure consistent formatting of your configuration files.
### 7.4 Deployment Best Practices
* **Blue-Green Deployment**: Use blue-green deployment to minimize downtime during deployments.
* **Canary Deployment**: Use canary deployment to test new Nginx configurations with a small subset of users before rolling them out to the entire user base.
* **Rollback Strategy**: Have a rollback strategy in place in case of deployment failures.
### 7.5 CI/CD Integration
* **Automated Testing**: Integrate automated testing into your CI/CD pipeline.
* **Configuration Validation**: Validate Nginx configuration files as part of your CI/CD pipeline.
* **Automated Deployment**: Automate the deployment of Nginx configuration files using CI/CD tools like Jenkins, GitLab CI, or CircleCI.
By following these best practices, you can create a robust, secure, and performant Nginx configuration that meets the needs of your web applications.