# Production environment configuration upstream cmc_php_production { server cmc-php-production:80; keepalive 32; } upstream cmc_go_production { server cmc-go-production:8080; keepalive 32; } # Rate limiting limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m; limit_req_zone $binary_remote_addr zone=api:10m rate=30r/m; server { server_name cmc.springupsoftware.com; # Basic auth for production auth_basic_user_file /etc/nginx/userpasswd; auth_basic "CMC Sales - Restricted Access"; # Security headers add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header Referrer-Policy "strict-origin-when-cross-origin"; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # Hide server information server_tokens off; # Request size limits client_max_body_size 50M; client_body_timeout 30s; client_header_timeout 30s; # Compression 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; # CakePHP legacy app routes location / { limit_req zone=api burst=10 nodelay; proxy_pass http://cmc_php_production; proxy_read_timeout 300s; proxy_connect_timeout 10s; proxy_send_timeout 30s; 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; # Buffer settings for better performance proxy_buffering on; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; } # Go API routes location /api/ { limit_req zone=api burst=20 nodelay; proxy_pass http://cmc_go_production; proxy_read_timeout 300s; proxy_connect_timeout 10s; proxy_send_timeout 30s; 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; # Buffer settings for better performance proxy_buffering on; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; } # Go page routes for emails location ~ ^/(emails|customers|products|purchase-orders|enquiries|documents) { limit_req zone=api burst=15 nodelay; proxy_pass http://cmc_go_production; proxy_read_timeout 300s; proxy_connect_timeout 10s; proxy_send_timeout 30s; 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; # Buffer settings for better performance proxy_buffering on; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; } # Static files from Go app with aggressive caching location /static/ { proxy_pass http://cmc_go_production; proxy_cache_valid 200 24h; add_header Cache-Control "public, max-age=86400"; expires 1d; } # PDF files with caching location /pdf/ { proxy_pass http://cmc_go_production; proxy_cache_valid 200 1h; add_header Cache-Control "public, max-age=3600"; expires 1h; } # Health check endpoints (no rate limiting) location /health { proxy_pass http://cmc_go_production/api/v1/health; access_log off; } # Block common attack patterns location ~ /\. { deny all; access_log off; log_not_found off; } location ~ ~$ { deny all; access_log off; log_not_found off; } # Error pages error_page 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } # Custom error page for rate limiting error_page 429 /429.html; location = /429.html { root /usr/share/nginx/html; } listen 80; }