Nginx反向代理无法访问Prometheus等Docker容器问题排查
问题解决方案:Nginx反向代理Prometheus/Grafana 404与Docker网络配置调整
一、修改Docker网络的Internal和Attachable属性
1. 针对已创建的现有网络
直接用docker network update命令修改:
# 开启Attachable属性,允许外部容器连接到该网络 docker network update --attachable=true <你的网络名称> # 关闭Internal属性,允许网络内容器与外部通信 docker network update --internal=false <你的网络名称>
2. 在Docker Compose中提前定义网络参数
在compose文件的networks块里直接配置:
networks: monitoring-net: driver: bridge internal: false # 允许网络与外部互通 attachable: true # 允许外部容器接入该网络
二、Nginx反向代理404问题核心修复
404的本质是:当你访问http://你的域名/prometheus时,Nginx默认把请求转发给Prometheus容器的/prometheus路径,但Prometheus/Grafana默认根路径是/,自然找不到对应资源。以下两种方案任选:
方案1:Nginx配置路径重写
在Nginx的server块里添加如下location规则:
server { listen 80; server_name localhost; # 保留你正常的根路径配置 location / { root /usr/share/nginx/html; index index.html index.htm; } # Prometheus反向代理 location /prometheus/ { # 重写路径,去掉/prometheus前缀后转发到Prometheus的根路径 rewrite ^/prometheus/(.*)$ /$1 break; proxy_pass http://prometheus:9090/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # Grafana反向代理 location /grafana/ { rewrite ^/grafana/(.*)$ /$1 break; proxy_pass http://grafana:3000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Grafana需要额外头部防止跳转错误 proxy_set_header X-Forwarded-Proto $scheme; } }
注意:访问时要带末尾斜杠,比如http://localhost/prometheus/,若不想带斜杠,可将location改为location /prometheus并调整rewrite规则。
方案2:修改Prometheus/Grafana的外部URL参数(推荐)
通过启动参数让服务自身适配子路径,避免Nginx复杂重写:
Prometheus配置(在Docker Compose的services块中)
prometheus: image: prom/prometheus:latest command: --config.file=/etc/prometheus/prometheus.yml --web.external-url=http://localhost/prometheus # 指定外部访问的URL前缀 --web.route-prefix=/ # 保持内部路由前缀为/ volumes: - ./prometheus/config:/etc/prometheus - prometheus-data:/prometheus networks: - monitoring-net
Grafana配置(在Docker Compose的services块中)
grafana: image: grafana/grafana:latest environment: - GF_SERVER_ROOT_URL=http://localhost/grafana # 指定外部访问根URL - GF_SERVER_SERVE_FROM_SUB_PATH=true # 开启子路径服务模式 - GF_SECURITY_ADMIN_PASSWORD=admin # 可自定义初始密码 volumes: - grafana-data:/var/lib/grafana networks: - monitoring-net
对应的Nginx配置可简化为:
location /prometheus/ { proxy_pass http://prometheus:9090/prometheus/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /grafana/ { proxy_pass http://grafana:3000/grafana/; 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; }
三、完整Docker Compose示例
整合所有配置的完整文件:
version: '3.8' services: nginx: image: nginx:alpine ports: - "80:80" volumes: - ./nginx/conf.d:/etc/nginx/conf.d # 挂载你的Nginx配置文件目录 - ./nginx/html:/usr/share/nginx/html networks: - monitoring-net depends_on: - prometheus - grafana prometheus: image: prom/prometheus:latest command: --config.file=/etc/prometheus/prometheus.yml --web.external-url=http://localhost/prometheus --web.route-prefix=/ volumes: - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - prometheus-data:/prometheus networks: - monitoring-net grafana: image: grafana/grafana:latest environment: - GF_SERVER_ROOT_URL=http://localhost/grafana - GF_SERVER_SERVE_FROM_SUB_PATH=true - GF_SECURITY_ADMIN_PASSWORD=admin volumes: - grafana-data:/var/lib/grafana networks: - monitoring-net volumes: prometheus-data: grafana-data: networks: monitoring-net: driver: bridge internal: false attachable: true
内容的提问来源于stack exchange,提问作者Oskar Paulsson
相关产品推荐
相关产品推荐

