使用Traefik反向代理子路径下的Grafana时出现404错误
解决Traefik反向代理Grafana子路径返回404的问题
嘿,我之前也碰到过一模一样的问题!你这404的根源其实是Grafana不知道自己运行在/grafana子路径下,再加上Traefik没正确处理请求路径的前缀转发,两者没对齐就会导致资源找不到。咱们一步步来解决:
1. 先给Grafana配置子路径适配
Grafana默认是根路径(/)提供服务的,当Traefik把/grafana开头的请求转发过去时,Grafana会傻愣愣地在自己的根目录下找资源,自然返回404。你需要给Grafana容器加两个关键环境变量:
GF_SERVER_ROOT_URL: 告诉Grafana它的外部访问完整地址(包括子路径)GF_SERVER_SERVE_FROM_SUB_PATH: 开启子路径服务模式
在你的docker-compose.yml里的grafana服务块加上这俩变量:
grafana: image: grafana/grafana restart: always environment: - GF_SERVER_ROOT_URL=https://metrics.mydomain/grafana - GF_SERVER_SERVE_FROM_SUB_PATH=true # 后续添加Traefik标签配置
2. 配置Traefik的路由与前缀剥离中间件
Traefik这边要做两件事:一是匹配/grafana开头的请求,二是把/grafana前缀去掉再转发给Grafana——不然Grafana收到的请求是/grafana/login,它只认/login,还是会404。这里要用Traefik的StripPrefix中间件。
给grafana服务加上Traefik的标签配置(同时确保Traefik已经挂载了Docker socket来自动发现服务):
grafana: # 上面的环境变量配置... labels: - "traefik.enable=true" # 路由规则:匹配metrics.mydomain域名下的/grafana路径 - "traefik.http.routers.grafana.rule=Host(`metrics.mydomain`) && PathPrefix(`/grafana`)" # 开启TLS(替换成你的证书解析器名称,比如Let's Encrypt的解析器) - "traefik.http.routers.grafana.tls=true" - "traefik.http.routers.grafana.tls.certresolver=your-cert-resolver" # 绑定前缀剥离中间件 - "traefik.http.routers.grafana.middlewares=grafana-strip-prefix" # 定义前缀剥离中间件:去掉/grafana前缀 - "traefik.http.middlewares.grafana-strip-prefix.stripprefix.prefixes=/grafana" # 指定转发到Grafana的默认端口3000 - "traefik.http.services.grafana.loadbalancer.server.port=3000"
同时检查Traefik服务的volumes,确保挂载了Docker socket来读取容器标签:
traefik: image: traefik restart: always ports: - 80:80 - 443:443 - 8080:8080 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro # 其他挂载(比如Traefik配置文件、证书存储)...
3. 验证与测试
先重启整个服务栈:
docker-compose down && docker-compose up -d
然后访问https://metrics.mydomain/grafana,应该就能正常进入Grafana登录页了。如果还是有问题,可以:
- 打开Traefik的dashboard(默认是
http://localhost:8080),检查grafana的路由和中间件是否正确加载 - 查看Grafana的日志,确认收到的请求路径是否已经被剥离了前缀:
docker-compose logs grafana
内容的提问来源于stack exchange,提问作者Ben Collins




