nginx.conf配置带路径location后出现404错误的原因排查
Nginx反向代理子路径404问题
我的nginx.conf内容如下:
events { worker_connections 1024; } http { server { listen 80; server_name localhost; location /prometheus/ { proxy_pass http://prometheus:9090/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /grafana/ { proxy_pass http://grafana:3000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } }
当把/prometheus/或/grafana/改为/时,应用能正常运行,但使用子路径访问时会出现404错误。所有应用均通过Docker运行。
问题原因
Prometheus、Grafana这类应用默认以根路径(/)生成内部链接和资源路径,通过Nginx子路径代理时,应用自身不知道当前上下文路径,生成的链接仍是/xxx而非/prometheus/xxx,导致访问404。
解决方法
方法1:配置应用上下文路径
- Prometheus:启动时添加
--web.external-url=http://localhost/prometheus/参数,让Prometheus自动为所有内部链接添加子路径前缀。
Docker启动命令示例:docker run -d --name prometheus -p 9090:9090 prom/prometheus --web.external-url=http://localhost/prometheus/ - Grafana:通过环境变量
GF_SERVER_ROOT_URL=http://localhost/grafana/设置上下文路径,让Grafana识别当前访问路径。
Docker启动命令示例:docker run -d --name grafana -p 3000:3000 -e GF_SERVER_ROOT_URL=http://localhost/grafana/ grafana/grafana
方法2:Nginx添加路径重写规则
若不想修改应用配置,可在Nginx的location块中添加重写规则,替换应用响应中的路径:
location /prometheus/ { proxy_pass http://prometheus:9090/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 替换响应中的根路径链接 sub_filter 'href="/' 'href="/prometheus/'; sub_filter 'src="/' 'src="/prometheus/'; sub_filter_once off; } location /grafana/ { proxy_pass http://grafana:3000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; sub_filter 'href="/' 'href="/grafana/'; sub_filter 'src="/' 'src="/grafana/'; sub_filter_once off; }
注意:使用sub_filter需确保Nginx安装了ngx_http_sub_module模块,多数发行版默认包含,若没有需重新编译Nginx添加该模块。
内容的提问来源于stack exchange,提问作者Fatemeh
相关产品推荐
相关产品推荐

