user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format json_combined escape=json '{' '"time_local":"$time_local",' '"remote_addr":"$remote_addr",' '"remote_user":"$remote_user",' '"request":"$request",' '"request_id":"$request_id",' '"request_host":"$host",' '"response_status": "$status",' '"body_bytes_sent":"$body_bytes_sent",' '"request_time":"$request_time",' '"http_referrer":"$http_referer",' '"http_user_agent":"$http_user_agent"' '}'; access_log /var/log/nginx/access.log json_combined; sendfile on; keepalive_timeout 65; 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_min_length 512; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss application/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon font/woff2; map $sent_http_content_type $cache_expires { default off; text/html epoch; text/css max; application/javascript max; ~image/ max; } server { listen 80; listen [::]:80; root /usr/share/nginx/html; index indexV2.html; access_log /dev/stdout; error_log /dev/stderr error; expires $cache_expires; # Redirect old /index.html requests to new file location = /index.html { return 301 /indexV2.html; } # Serve indexV2.html directly without redirect loop location = /indexV2.html { root /usr/share/nginx/html; } # Fallback for SPA routing — all unmatched routes go to indexV2.html location / { try_files $uri /indexV2.html; } } # Healthcheck server { listen 8080; location /health { add_header Content-Type text/plain; return 200 'OK'; } } }