# Docker DNS resolver (127.0.0.11 = Docker's embedded DNS). # Required for variable-based proxy_pass below to resolve upstream # hostnames on each request instead of caching them at startup. # Without this, when backend/frontend containers are recreated (new IP), # nginx keeps pointing to stale IPs → 502 Bad Gateway. # Valid=10s re-resolves at most every 10 seconds to avoid excessive DNS queries. resolver 127.0.0.11 ipv6=off valid=10s; map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; server_name imphnen.asepharyana.my.id; # API proxy — matches /api and /api/* location ^~ /api { set $backend_url "http://backend:3000"; proxy_pass $backend_url$uri$is_args$args; 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; } # WebSocket proxy — matches /ws and /ws/* location ^~ /ws { set $backend_url "http://backend:3000"; proxy_pass $backend_url$uri$is_args$args; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; 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; # WebSocket-specific: no buffering, longer timeouts proxy_buffering off; proxy_read_timeout 86400s; proxy_send_timeout 86400s; } # Frontend SPA fallback location / { set $frontend_url "http://frontend:3000"; proxy_pass $frontend_url$uri$is_args$args; 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; } }