Docker化JHipster应用在Nginx反向代理后无法正常运行
Nginx SSL反向代理访问异常排查
我在服务器上通过SSL运行Nginx反向代理,域名为mydomain.com,对应的Nginx配置如下:
user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream myApp { server my-app:8080; } server { listen 80; server_name mydomain.com; root /usr/share/nginx/html; return 301 https://$host$request_uri; } server{ listen 443 ssl; root /usr/share/nginx/html; server_name mydomain.com; include /etc/nginx/mime.types; ssl_protocols TLSv1.2 TLSv1.3 TLSv1.1; ssl_certificate /etc/nginx/certs/myapp_chain.pem; ssl_certificate_key /etc/nginx/certs/private.pem; proxy_set_header X-Forwarded-For $proxy_protocol_addr; # 转发客户端原始IP proxy_set_header X-Forwarded-Proto $scheme; # 转发原始协议(HTTP/HTTPS) proxy_set_header Host $host; # 转发客户端请求的原始主机名 proxy_buffers 4 256k; proxy_buffer_size 128k; proxy_busy_buffers_size 256k; location / { index index.html; try_files $uri $uri/ /index.html; } location /portal { proxy_pass http://myApp/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } }
本地环境及非代理环境下应用均可正常访问,但通过mydomain.com/portal访问时出现错误,且已开启CORS,浏览器控制台报错如下:


问题原因及修复方案
1. X-Forwarded-For 配置无效
当前配置中使用$proxy_protocol_addr获取客户端IP,但该变量仅在Nginx监听端口启用proxy_protocol时生效(需配置listen 443 ssl proxy_protocol;),否则会返回空值,导致后端无法正确识别客户端来源。
修复:
将server块中的X-Forwarded-For配置改为:
proxy_set_header X-Forwarded-For $remote_addr;
如果是多层代理场景,需要保留上游代理的IP信息,改为:
proxy_set_header X-Forwarded-For $remote_addr, $http_x_forwarded_for;
2. 前端资源路径不匹配
location /portal中的proxy_pass http://myApp/;会将请求路径中的/portal移除后转发到后端,导致前端页面中相对路径的资源(如JS、CSS)会直接请求mydomain.com/static/xxx,而非正确的mydomain.com/portal/static/xxx,引发404错误。
修复方案二选一:
- 方案A:调整后端应用路径前缀
在后端应用中配置路径前缀(如Spring Boot设置server.servlet.context-path=/portal),让后端生成的资源路径自动带上/portal,适配反向代理的路径映射。 - 方案B:修改Nginx代理配置
去掉proxy_pass末尾的斜杠,让Nginx完整转发/portal路径给后端:
此时后端应用需要能处理以location /portal { proxy_pass http://myApp; proxy_set_header X-Real-IP $remote_addr; }/portal开头的请求。
3. 冗余Header配置
server块中已经设置了proxy_set_header Host $host;,location块中重复设置了相同内容,可去掉location块中的重复项,减少冗余配置。
修改后的完整配置示例
user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream myApp { server my-app:8080; } server { listen 80; server_name mydomain.com; root /usr/share/nginx/html; return 301 https://$host$request_uri; } server{ listen 443 ssl; root /usr/share/nginx/html; server_name mydomain.com; include /etc/nginx/mime.types; ssl_protocols TLSv1.2 TLSv1.3 TLSv1.1; ssl_certificate /etc/nginx/certs/myapp_chain.pem; ssl_certificate_key /etc/nginx/certs/private.pem; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host; proxy_buffers 4 256k; proxy_buffer_size 128k; proxy_busy_buffers_size 256k; location / { index index.html; try_files $uri $uri/ /index.html; } location /portal { proxy_pass http://myApp; proxy_set_header X-Real-IP $remote_addr; } } }
内容的提问来源于stack exchange,提问作者Houssam Badri
相关产品推荐
相关产品推荐

