Setting up Nginx as a reverse proxy with Apache backend is a powerful architecture that combines the best of both web servers. This configuration leverages Nginx's excellent performance for static content and SSL termination while utilizing Apache's robust module ecosystem and .htaccess support for dynamic content processing.
This comprehensive guide covers the complete setup process, from basic configuration to advanced optimization techniques for production environments.
Understanding Nginx Reverse Proxy Architecture
What is a Reverse Proxy?
A reverse proxy sits between clients and backend servers, forwarding client requests to appropriate backend servers and returning responses back to clients. Unlike a forward proxy that acts on behalf of clients, a reverse proxy acts on behalf of servers.
Benefits of Nginx + Apache Architecture
Component | Role | Advantages |
---|---|---|
Nginx (Frontend) | Reverse Proxy | Fast static content delivery, SSL termination, load balancing |
Apache (Backend) | Application Server | Rich module ecosystem, .htaccess support, PHP processing |
Architecture Overview
Client Request β Nginx (Port 80/443) β Apache (Port 8080) β Response
Key Benefits:
- Performance: Nginx handles static files and SSL efficiently
- Scalability: Easy horizontal scaling with multiple Apache backends
- Security: Nginx acts as a security layer protecting Apache
- Flexibility: Combine strengths of both web servers
- Resource Optimization: Better memory and CPU utilization
Prerequisites and System Requirements
System Requirements
- Operating System: Ubuntu 20.04 LTS, CentOS 8, or RHEL 8
- Memory: Minimum 2GB RAM (4GB+ recommended for production)
- CPU: 2+ cores recommended
- Storage: At least 20GB available space
- Network: Static IP address for production environments
Required Packages
- Nginx: Latest stable version (1.18+)
- Apache: Version 2.4+
- SSL Certificates: Let's Encrypt or commercial certificates
- Firewall: UFW (Ubuntu) or firewalld (CentOS/RHEL)
Pre-installation Checklist
# Check system resources
free -h
df -h
nproc
# Verify network configuration
ip addr show
ss -tlnp | grep -E ':80|:443|:8080'
# Update system packages
sudo apt update && sudo apt upgrade -y # Ubuntu/Debian
sudo dnf update -y # CentOS/RHEL 8
Installation Process
Step 1: Install Nginx
Ubuntu/Debian Installation
# Update package repository
sudo apt update
# Install Nginx
sudo apt install nginx -y
# Start and enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
# Verify installation
nginx -v
sudo systemctl status nginx
CentOS/RHEL Installation
# Install EPEL repository
sudo dnf install epel-release -y
# Install Nginx
sudo dnf install nginx -y
# Start and enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
# Verify installation
nginx -v
sudo systemctl status nginx
Step 2: Install Apache
Ubuntu/Debian Installation
# Install Apache
sudo apt install apache2 -y
# Stop Apache (we'll configure it for backend use)
sudo systemctl stop apache2
# Verify installation
apache2 -v
CentOS/RHEL Installation
# Install Apache
sudo dnf install httpd -y
# Stop Apache
sudo systemctl stop httpd
# Verify installation
httpd -v
Step 3: Configure Apache Backend
Change Apache Default Port
# Ubuntu/Debian
sudo nano /etc/apache2/ports.conf
# CentOS/RHEL
sudo nano /etc/httpd/conf/httpd.conf
Edit ports.conf (Ubuntu/Debian):
# Change from Listen 80 to:
Listen 8080
# If SSL is enabled, change from Listen 443 to:
Listen 8443
Edit httpd.conf (CentOS/RHEL):
# Change from Listen 80 to:
Listen 8080
# Add SSL port if needed:
Listen 8443
Configure Apache Virtual Host
# Ubuntu/Debian
sudo nano /etc/apache2/sites-available/backend.conf
# CentOS/RHEL
sudo nano /etc/httpd/conf.d/backend.conf
Backend Virtual Host Configuration:
<VirtualHost *:8080>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/html
# Enable mod_rewrite
<Directory /var/www/html>
AllowOverride All
Require all granted
</Directory>
# Logging
ErrorLog ${APACHE_LOG_DIR}/backend_error.log
CustomLog ${APACHE_LOG_DIR}/backend_access.log combined
# Security headers
Header always set X-Backend-Server "Apache"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
</VirtualHost>
Enable Required Apache Modules
# Ubuntu/Debian
sudo a2enmod rewrite
sudo a2enmod headers
sudo a2enmod ssl
sudo a2ensite backend.conf
sudo a2dissite 000-default.conf
# CentOS/RHEL (modules are typically enabled by default)
# Verify modules are loaded
sudo httpd -M | grep -E 'rewrite|headers|ssl'
Start Apache Backend
# Ubuntu/Debian
sudo systemctl start apache2
sudo systemctl enable apache2
# CentOS/RHEL
sudo systemctl start httpd
sudo systemctl enable httpd
# Verify Apache is running on port 8080
sudo ss -tlnp | grep :8080
Nginx Reverse Proxy Configuration
Step 1: Basic Nginx Configuration
Main Nginx Configuration
sudo nano /etc/nginx/nginx.conf
Optimized nginx.conf:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# Optimize worker connections
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
http {
# Basic settings
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging format
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';
access_log /var/log/nginx/access.log main;
# Performance optimizations
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 100M;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# Hide Nginx version
server_tokens off;
# Include virtual host configurations
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Step 2: Create Reverse Proxy Virtual Host
# Ubuntu/Debian
sudo nano /etc/nginx/sites-available/reverse-proxy.conf
# CentOS/RHEL
sudo nano /etc/nginx/conf.d/reverse-proxy.conf
Reverse Proxy Configuration:
# Upstream backend servers
upstream apache_backend {
# Single backend server
server 127.0.0.1:8080;
# For multiple backend servers (load balancing)
# server 127.0.0.1:8080 weight=3;
# server 127.0.0.1:8081 weight=2;
# server 127.0.0.1:8082 weight=1;
# Health check and failover
# server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
# Keep connections alive
keepalive 32;
}
# HTTP server block (redirect to HTTPS)
server {
listen 80;
server_name example.com www.example.com;
# Redirect all HTTP traffic to HTTPS
return 301 https://$server_name$request_uri;
}
# HTTPS server block
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL Configuration
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
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;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Document root for static files
root /var/www/html;
index index.php index.html index.htm;
# Handle static files directly with Nginx
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
# Try to serve static files directly, fallback to Apache
try_files $uri @apache;
}
# Handle PHP and dynamic content
location ~ \.php$ {
proxy_pass http://apache_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;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
# Proxy timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Buffer settings
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
# Don't cache dynamic content
proxy_no_cache 1;
proxy_cache_bypass 1;
}
# Default location - proxy to Apache
location / {
try_files $uri $uri/ @apache;
}
# Apache backend proxy
location @apache {
proxy_pass http://apache_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;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
# Proxy timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Buffer settings
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
}
# Security: Block access to sensitive files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
location ~ ~$ {
deny all;
access_log off;
log_not_found off;
}
# Block access to Apache config files
location ~ /\.ht {
deny all;
access_log off;
log_not_found off;
}
# Custom error pages
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Step 3: Enable and Test Configuration
Enable Site (Ubuntu/Debian)
sudo ln -s /etc/nginx/sites-available/reverse-proxy.conf /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
Test Nginx Configuration
# Test configuration syntax
sudo nginx -t
# If successful, reload Nginx
sudo systemctl reload nginx
# Check Nginx status
sudo systemctl status nginx
SSL Certificate Setup
Option 1: Let's Encrypt (Recommended)
Install Certbot
# Ubuntu/Debian
sudo apt install certbot python3-certbot-nginx -y
# CentOS/RHEL
sudo dnf install certbot python3-certbot-nginx -y
Obtain SSL Certificate
# Stop Nginx temporarily
sudo systemctl stop nginx
# Obtain certificate
sudo certbot certonly --standalone -d example.com -d www.example.com
# Start Nginx
sudo systemctl start nginx
# Set up automatic renewal
sudo crontab -e
# Add this line:
# 0 12 * * * /usr/bin/certbot renew --quiet
Update Nginx Configuration for Let's Encrypt
sudo nano /etc/nginx/sites-available/reverse-proxy.conf
Update SSL paths:
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
Option 2: Self-Signed Certificate (Development)
# Create SSL directory
sudo mkdir -p /etc/ssl/private
# Generate private key
sudo openssl genrsa -out /etc/ssl/private/example.com.key 2048
# Generate certificate
sudo openssl req -new -x509 -key /etc/ssl/private/example.com.key \
-out /etc/ssl/certs/example.com.crt -days 365 \
-subj "/C=US/ST=State/L=City/O=Organization/CN=example.com"
# Set proper permissions
sudo chmod 600 /etc/ssl/private/example.com.key
sudo chmod 644 /etc/ssl/certs/example.com.crt
Firewall Configuration
Ubuntu/Debian (UFW)
# Enable UFW
sudo ufw enable
# Allow SSH
sudo ufw allow ssh
# Allow HTTP and HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Block direct access to Apache
sudo ufw deny 8080/tcp
# Check status
sudo ufw status
CentOS/RHEL (firewalld)
# Start and enable firewalld
sudo systemctl start firewalld
sudo systemctl enable firewalld
# Allow HTTP and HTTPS
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# Block direct access to Apache
sudo firewall-cmd --permanent --remove-port=8080/tcp
# Reload firewall
sudo firewall-cmd --reload
# Check status
sudo firewall-cmd --list-all
Performance Optimization
Nginx Caching Configuration
Create Cache Directory
sudo mkdir -p /var/cache/nginx/proxy
sudo chown nginx:nginx /var/cache/nginx/proxy
sudo chmod 755 /var/cache/nginx/proxy
Add Caching to Nginx Configuration
# Add to http block in nginx.conf
proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=my_cache:10m
max_size=1g inactive=60m use_temp_path=off;
# Add to server block
location / {
# Cache configuration
proxy_cache my_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
# Cache headers
add_header X-Cache-Status $upstream_cache_status;
# Existing proxy settings...
proxy_pass http://apache_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;
proxy_set_header X-Forwarded-Proto $scheme;
}
Apache Backend Optimization
Configure Apache for Backend Use
# Ubuntu/Debian
sudo nano /etc/apache2/apache2.conf
# CentOS/RHEL
sudo nano /etc/httpd/conf/httpd.conf
Apache Optimization:
# Reduce memory usage
ServerLimit 4
MaxRequestWorkers 100
ThreadsPerChild 25
# Disable unnecessary modules
# LoadModule status_module modules/mod_status.so
# LoadModule info_module modules/mod_info.so
# Enable compression
LoadModule deflate_module modules/mod_deflate.so
<Location />
SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \
\.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
</Location>
# Security: Hide server information
ServerTokens Prod
ServerSignature Off
# Disable server-status and server-info
<Location "/server-status">
Require all denied
</Location>
<Location "/server-info">
Require all denied
</Location>
Load Balancing Configuration
Multiple Apache Backend Servers
Configure Additional Apache Instances
# Copy Apache configuration for second instance
sudo cp -r /etc/apache2 /etc/apache2-8081 # Ubuntu/Debian
sudo cp -r /etc/httpd /etc/httpd-8081 # CentOS/RHEL
# Edit second instance configuration
sudo nano /etc/apache2-8081/ports.conf # Ubuntu/Debian
sudo nano /etc/httpd-8081/conf/httpd.conf # CentOS/RHEL
# Change port to 8081
Listen 8081
# Create systemd service for second instance
sudo nano /etc/systemd/system/apache2-8081.service
Systemd Service File:
[Unit]
Description=Apache HTTP Server (Instance 8081)
After=network.target
[Service]
Type=forking
ExecStart=/usr/sbin/apache2 -f /etc/apache2-8081/apache2.conf -DFOREGROUND
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Update Nginx Upstream Configuration
upstream apache_backend {
# Load balancing methods
# least_conn; # Route to server with least connections
# ip_hash; # Route based on client IP
server 127.0.0.1:8080 weight=3 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8081 weight=2 max_fails=3 fail_timeout=30s;
server 127.0.0.1:8082 weight=1 max_fails=3 fail_timeout=30s backup;
keepalive 32;
}
Health Check Configuration
Nginx Health Check
# Add to server block
location /nginx-health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# Backend health check
location /backend-health {
proxy_pass http://apache_backend/server-status;
proxy_set_header Host $host;
access_log off;
}
Apache Health Check
# Enable mod_status for health checks
LoadModule status_module modules/mod_status.so
<Location "/server-status">
SetHandler server-status
Require ip 127.0.0.1
Require ip ::1
</Location>
Monitoring and Logging
Nginx Monitoring
Custom Log Format
# Add to nginx.conf http block
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time" '
'cache="$upstream_cache_status"';
# Use in server block
access_log /var/log/nginx/detailed.log detailed;
Log Rotation
# Create logrotate configuration
sudo nano /etc/logrotate.d/nginx-custom
Logrotate Configuration:
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 644 nginx nginx
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
Performance Monitoring Script
# Create monitoring script
sudo nano /usr/local/bin/nginx-apache-monitor.sh
Monitoring Script:
#!/bin/bash
LOG_FILE="/var/log/nginx-apache-monitor.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$DATE] Starting monitoring check" >> $LOG_FILE
# Check Nginx status
if systemctl is-active --quiet nginx; then
echo "[$DATE] Nginx: RUNNING" >> $LOG_FILE
else
echo "[$DATE] Nginx: STOPPED - Attempting restart" >> $LOG_FILE
systemctl restart nginx
fi
# Check Apache status
if systemctl is-active --quiet apache2 || systemctl is-active --quiet httpd; then
echo "[$DATE] Apache: RUNNING" >> $LOG_FILE
else
echo "[$DATE] Apache: STOPPED - Attempting restart" >> $LOG_FILE
systemctl restart apache2 || systemctl restart httpd
fi
# Check backend connectivity
if curl -s http://127.0.0.1:8080 > /dev/null; then
echo "[$DATE] Backend: ACCESSIBLE" >> $LOG_FILE
else
echo "[$DATE] Backend: INACCESSIBLE" >> $LOG_FILE
fi
# Check disk space
DISK_USAGE=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $DISK_USAGE -gt 80 ]; then
echo "[$DATE] WARNING: Disk usage at ${DISK_USAGE}%" >> $LOG_FILE
fi
# Check memory usage
MEM_USAGE=$(free | awk 'NR==2{printf "%.2f", $3*100/$2}')
echo "[$DATE] Memory usage: ${MEM_USAGE}%" >> $LOG_FILE
echo "[$DATE] Monitoring check completed" >> $LOG_FILE
# Make script executable
sudo chmod +x /usr/local/bin/nginx-apache-monitor.sh
# Add to crontab for regular monitoring
sudo crontab -e
# Add: */5 * * * * /usr/local/bin/nginx-apache-monitor.sh
Troubleshooting Common Issues
Issue 1: 502 Bad Gateway Error
Symptoms:
502 Bad Gateway
nginx/1.18.0
Diagnosis:
# Check if Apache is running
sudo systemctl status apache2 # Ubuntu/Debian
sudo systemctl status httpd # CentOS/RHEL
# Check if Apache is listening on correct port
sudo ss -tlnp | grep :8080
# Check Nginx error logs
sudo tail -f /var/log/nginx/error.log
# Check Apache error logs
sudo tail -f /var/log/apache2/error.log # Ubuntu/Debian
sudo tail -f /var/log/httpd/error_log # CentOS/RHEL
Solutions:
# Restart Apache
sudo systemctl restart apache2 # Ubuntu/Debian
sudo systemctl restart httpd # CentOS/RHEL
# Check firewall rules
sudo ufw status # Ubuntu/Debian
sudo firewall-cmd --list-all # CentOS/RHEL
# Verify upstream configuration
sudo nginx -t
Issue 2: SSL Certificate Problems
Symptoms:
SSL_ERROR_BAD_CERT_DOMAIN
ERR_CERT_COMMON_NAME_INVALID
Solutions:
# Check certificate validity
sudo openssl x509 -in /etc/ssl/certs/example.com.crt -text -noout
# For Let's Encrypt certificates
sudo certbot certificates
# Renew Let's Encrypt certificate
sudo certbot renew --dry-run
# Check SSL configuration
sudo nginx -t
Issue 3: Performance Issues
Diagnosis:
# Check server resources
htop
iotop
free -h
df -h
# Monitor connections
sudo ss -s
sudo netstat -an | grep :80 | wc -l
# Check Nginx status
curl http://localhost/nginx-health
# Monitor backend response times
curl -w "@curl-format.txt" -o /dev/null -s http://example.com/
Create curl-format.txt:
time_namelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_pretransfer: %{time_pretransfer}\n
time_redirect: %{time_redirect}\n
time_starttransfer: %{time_starttransfer}\n
----------\n
time_total: %{time_total}\n
Security Best Practices
Nginx Security Configuration
# Add to server block
# Rate limiting
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
location /login {
limit_req zone=login burst=5 nodelay;
proxy_pass http://apache_backend;
}
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://apache_backend;
}
# Block common attack patterns
location ~* \.(php|asp|aspx|jsp)$ {
if ($request_uri ~* "(union|select|insert|delete|drop|create|alter|exec|script)") {
return 403;
}
proxy_pass http://apache_backend;
}
# Block suspicious user agents
if ($http_user_agent ~* (nmap|nikto|wikto|sf|sqlmap|bsqlbf|w3af|acunetix|havij|appscan)) {
return 403;
}
Apache Security Configuration
# Add to Apache configuration
# Hide Apache version
ServerTokens Prod
ServerSignature Off
# Disable unnecessary HTTP methods
<Location />
<LimitExcept GET POST HEAD>
Require all denied
</LimitExcept>
</Location>
# Security headers
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
# Disable server-info and server-status from external access
<Location "/server-info">
Require ip 127.0.0.1
Require ip ::1
</Location>
<Location "/server-status">
Require ip 127.0.0.1
Require ip ::1
</Location>
Conclusion
Setting up Nginx as a reverse proxy with Apache backend provides a robust, scalable, and high-performance web server architecture. This configuration combines the strengths of both servers while providing excellent security and optimization opportunities.
Key Benefits Achieved
- Performance: Nginx handles static content and SSL termination efficiently
- Scalability: Easy horizontal scaling with load balancing
- Security: Multiple layers of protection and security headers
- Flexibility: Support for both static and dynamic content
- Monitoring: Comprehensive logging and health checking
Best Practices Summary
- Regular Updates: Keep both Nginx and Apache updated
- Monitoring: Implement comprehensive monitoring and alerting
- Security: Regular security audits and configuration reviews
- Backup: Regular configuration and SSL certificate backups
- Testing: Test all changes in staging environment first
Performance Optimization Checklist
- β Enable Gzip compression
- β Configure proper caching headers
- β Implement proxy caching
- β Optimize buffer sizes
- β Enable HTTP/2
- β Use keepalive connections
- β Monitor and tune worker processes
Security Checklist
- β SSL/TLS encryption enabled
- β Security headers configured
- β Rate limiting implemented
- β Firewall properly configured
- β Regular security updates
- β Access logs monitored
- β Unnecessary services disabled
This architecture provides a solid foundation for hosting modern web applications with excellent performance, security, and scalability characteristics. Regular monitoring and maintenance ensure optimal operation in production environments.
For advanced configurations and specific use cases, refer to the official documentation for Nginx and Apache web servers.