The Ultimate DevOps Playbook: Tuning Nginx, Gunicorn/FPM, and Elasticsearch on AWS for Magento 2
Nginx Configuration for Magento 2 on AWS
Optimizing Nginx is crucial for serving static assets efficiently and proxying dynamic requests to your Magento 2 application. On AWS, leveraging Elastic Load Balancers (ELBs) or Application Load Balancers (ALBs) in front of Nginx instances requires specific configurations to ensure proper health checks, SSL termination, and request routing.
SSL Termination and HTTP/2
When using an ALB for SSL termination, Nginx will receive unencrypted HTTP traffic. It’s essential to enable HTTP/2 for improved performance. If Nginx is directly exposed (less common in production AWS setups), you’d configure SSL here.
Here’s a sample Nginx configuration snippet for a server block, assuming traffic is coming from an ALB (port 80):
Example Nginx Server Block (from ALB)
server {
listen 80 http2;
server_name your-magento-domain.com;
# Enable Gzip compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
# Define root and index files
root /var/www/magento2/public_html;
index index.php index.html index.htm;
# Magento 2 specific location blocks
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Static assets caching
location ~* ^/(media|static)/ {
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
log_not_found off;
}
# PHP-FPM configuration (assuming FPM is running on a separate socket or port)
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; # Adjust PHP version and path
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param MAGE_RUN_CODE "your_magento_store_code"; # Set your Magento store code
fastcgi_param MAGE_RUN_TYPE "store"; # Or "website"
}
# Deny access to sensitive files
location ~ /\.ht {
deny all;
}
# Deny access to .git directory
location ~ /\.git {
deny all;
}
# Error pages
error_page 404 /errors/404.php;
error_page 500 502 503 504 /errors/50x.php;
}
Tuning Nginx Worker Processes and Connections
The worker_processes directive controls how many worker processes Nginx will spawn. Setting it to auto is often a good starting point, allowing Nginx to determine the optimal number based on CPU cores. worker_connections defines the maximum number of simultaneous connections that each worker process can handle.
Nginx Global Configuration Snippet
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 4096; # Adjust based on system limits and expected load
multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off; # Important for security
# Include other configurations
include /etc/nginx/mime.types;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Tuning Considerations:
worker_processes: Set toautoor the number of CPU cores.worker_connections: This is limited by the system’s file descriptor limit. Ensureulimit -nis set high enough (e.g., 65536 or more) for the Nginx user.keepalive_timeout: A shorter timeout can free up connections faster, but too short can increase overhead.sendfile on;: Crucial for efficient file transfers.tcp_nopush on;andtcp_nodelay on;: Optimize TCP packet sending.
Gunicorn/PHP-FPM Tuning for Magento 2
Magento 2 is a PHP application. The choice is typically between PHP-FPM (for Nginx) or Gunicorn (if using a Python-based framework or a reverse proxy setup for PHP, which is less common for direct Magento deployments).
PHP-FPM Tuning
PHP-FPM (FastCGI Process Manager) is the standard way to interface PHP with web servers like Nginx. Tuning its process management is critical for handling concurrent requests.
PHP-FPM Pool Configuration (`www.conf`)
The primary configuration file is usually located at /etc/php/8.1/fpm/pool.d/www.conf (adjust version and path as needed). The most important directives are related to process management.
; /etc/php/8.1/fpm/pool.d/www.conf [www] user = www-data group = www-data listen = /var/run/php/php8.1-fpm.sock ; Or a TCP port like 127.0.0.1:9000 ; Process Manager Control ; pm = dynamic ; Options: static, dynamic, ondemand pm = dynamic ; If pm.max_children is set to 'static', this is the number of child processes. ; If pm.max_children is set to 'dynamic' or 'ondemand', this is the maximum number of child processes that will be spawned. pm.max_children = 100 ; Adjust based on available RAM and expected load ; If pm.max_children is set to 'dynamic', this is the desired number of child processes on average. pm.min_spare_servers = 10 ; Adjust based on expected load fluctuations pm.max_spare_servers = 20 ; Adjust based on expected load fluctuations ; If pm.max_children is set to 'ondemand', this is the number of child processes to be created on startup. ; pm.max_children = 5 ; If pm.max_children is set to 'ondemand', this is the maximum number of child processes that will be spawned. ; pm.max_children = 10 ; If pm.max_children is set to 'ondemand', this is the number of seconds each child process will live before being killed. ; pm.process_idle_timeout = 10s ; The number of requests each child process should execute before reexecuting. ; Setting this to 0 means infinite. pm.max_requests = 500 ; Helps prevent memory leaks ; Other important settings request_terminate_timeout = 60s ; Timeout for script execution ; rlimit_files = 1024 ; Adjust based on system limits ; rlimit_core = 0 ; Set to 0 to disable core dumps ; listen.owner = www-data ; listen.group = www-data ; listen.mode = 0660 ; listen.acl = ; listen.backlog = -1 ; pm.status_path = /status ; pm.ping.path = /ping ; pm.ping.response = pong ; pm.emergency_restart_threshold = 10 ; pm.emergency_restart_interval = 10s ; pm.process_max = 128
Tuning Considerations:
pm:dynamicis generally recommended.staticcan offer slightly better performance but consumes more memory.ondemandis good for very low traffic but can have higher latency on initial requests.pm.max_children: This is the most critical setting. It dictates how many PHP processes can run concurrently. Calculate this based on your server’s RAM. A rough estimate:(Total RAM - RAM for OS/Nginx/DB) / Average RAM per PHP process. Magento processes can be memory-intensive. Start conservatively and monitor.pm.max_requests: Setting this prevents memory leaks from accumulating over time. A value between 250-1000 is common.request_terminate_timeout: Ensure this is long enough for your longest-running Magento operations but not so long that it hangs indefinitely.
Gunicorn Tuning (If Applicable)
While not directly used for serving Magento 2 PHP, Gunicorn might be used in a microservices architecture or for other components. Its tuning focuses on worker processes and threads.
Example Gunicorn Command Line
gunicorn --workers 3 --threads 2 --bind 0.0.0.0:8000 myapp.wsgi:application
Tuning Considerations:
--workers: Typically set to(2 * number_of_cpu_cores) + 1.--threads: For I/O-bound applications, increasing threads can improve concurrency.--worker-class: Considergeventoreventletfor asynchronous I/O.
Elasticsearch Tuning on AWS
Elasticsearch is vital for Magento 2’s catalog search and other features. Performance tuning involves JVM heap size, shard allocation, and indexing settings.
JVM Heap Size Configuration
The JVM heap size is configured in jvm.options, typically found in /etc/elasticsearch/jvm.options or similar paths depending on your installation method (e.g., Docker, package manager).
Example `jvm.options`
# /etc/elasticsearch/jvm.options # Enable GC logging -Xlog:gc*:file=/var/log/elasticsearch/gc.log:time,uptime,level,tags:filecount=32,filesize=64m # Heap Size # Set Xms and Xmx to the same value to prevent resizing # Rule of thumb: No more than 50% of system RAM, and not exceeding 30-32GB. -Xms4g -Xmx4g
Tuning Considerations:
- Set
-Xmsand-Xmxto the same value. - Allocate no more than 50% of the server’s RAM to the Elasticsearch heap.
- Avoid exceeding 30-32GB due to compressed ordinary object pointers (compressed oops). If you need more than 32GB, consider alternative JVMs or architectures.
- Monitor garbage collection (GC) activity. Frequent or long GC pauses indicate heap issues.
Shard Allocation and Indexing Settings
Proper shard management and indexing settings are crucial for search performance and stability.
Index Settings API Example
You can adjust settings dynamically using the Index Settings API. For Magento 2, the primary index is usually named `magento2`. You can check current settings with:
GET /magento2/_settings
To update settings (e.g., number of replicas, refresh interval):
PUT /magento2/_settings
{
"index" : {
"number_of_shards" : "5",
"number_of_replicas" : "1",
"refresh_interval" : "30s"
}
}
Tuning Considerations:
number_of_shards: Should ideally match the number of data nodes in your cluster for even distribution. Too many shards can increase overhead. Magento’s default is often reasonable, but can be tuned.number_of_replicas: Set to1for high availability. Increase for read-heavy workloads if performance is bottlenecked by read capacity.refresh_interval: The default is1s, making documents searchable almost immediately. For high-volume indexing, increasing this to5s,10s, or even30scan significantly improve indexing throughput at the cost of slightly delayed search visibility.- Consider using Index Lifecycle Management (ILM) for managing indices over time, especially if you have time-series data or need to archive/delete old data.
AWS Specific Considerations
When deploying on AWS, leverage managed services and instance types optimized for your workload.
- EC2 Instance Types: Choose instance types with sufficient vCPUs and RAM for Nginx, PHP-FPM, and Elasticsearch. Memory-optimized (R series) or compute-optimized (C series) instances are often suitable.
- EBS Volumes: Use provisioned IOPS (io1/io2) or General Purpose SSD (gp3) volumes for Elasticsearch data directories to ensure consistent I/O performance.
- Security Groups: Configure security groups to allow traffic only from necessary sources (e.g., ALB to Nginx, Nginx to PHP-FPM, application to Elasticsearch).
- CloudWatch: Set up comprehensive monitoring for CPU utilization, memory usage, disk I/O, network traffic, and application-specific metrics (e.g., PHP-FPM active processes, Elasticsearch cluster health).
- Elasticsearch Service (AWS Managed Elasticsearch): Consider using AWS Elasticsearch Service for managed Elasticsearch clusters. This offloads operational burden but requires careful configuration of instance types, storage, and access policies.