You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Nginx反向代理子路径重定向丢前缀404问题

问题原因

路径前缀丢失由两个配置缺失共同导致:

  • Nginx反向代理规则未传递代理相关标准请求头、未重写后端返回的跳转地址,且对无末尾斜杠的子路径访问未做归一化处理
  • Jenkins、Grafana默认以域名根路径为部署上下文,未配置子路径挂载参数,生成跳转链接、静态资源路径时默认从根路径起始,不会自动携带服务前缀
修复步骤

1. 配置后端服务的子路径上下文

两个服务都需要显式声明自己被挂载的子路径,才能正确生成内部跳转链接。
修改docker-compose.yml中对应服务的配置,保留原有所有配置不变,新增环境变量段:

Jenkins配置

jenkins:
    # 此处保留原有build、volumes、ports等所有配置不变
    environment:
      - JENKINS_OPTS=--prefix=/jenkins

Grafana配置

grafana:
    # 此处保留原有image、volumes、ports等所有配置不变
    environment:
      - GF_SERVER_ROOT_URL=http://myapp.fr/grafana/
      - GF_SERVER_SERVE_FROM_SUB_PATH=true

可选优化:如果不需要直接通过宿主机端口访问Jenkins、Grafana,可以删除两个服务下的ports段,仅保留Nginx的端口映射,让后端服务仅在Docker内部网络可达,提升安全性。

2. 修正Nginx反向代理规则

替换原有配置中/jenkins/、/grafana/两个location段的内容,新增无斜杠路径归一化规则、代理头传递、跳转重写、websocket兼容配置:

server {
    listen       80;
    listen  [::]:80;
    server_name  myapp.fr;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    # 无末尾斜杠路径自动归一化,避免匹配不到代理规则
    location = /jenkins {
        return 301 /jenkins/;
    }
    location = /grafana {
        return 301 /grafana/;
    }

    location /jenkins/ {
        # 注意:proxy_pass末尾不要加斜杠,避免前缀被Nginx自动剥离
        proxy_pass http://jenkins:8080;
        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;
        # 自动重写后端返回的跳转地址,补全/jenkins前缀
        proxy_redirect http://$host/ http://$host/jenkins/;
        proxy_redirect https://$host/ https://$host/jenkins/;
        # 兼容Jenkins插件、实时日志需要的websocket连接
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        add_header Access-Control-Allow-Origin '*';
    }

    location /grafana/ {
        # 注意:proxy_pass末尾不要加斜杠,避免前缀被Nginx自动剥离
        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;
        proxy_set_header X-Forwarded-Proto $scheme;
        # 自动重写后端返回的跳转地址,补全/grafana前缀
        proxy_redirect http://$host/ http://$host/grafana/;
        proxy_redirect https://$host/ https://$host/grafana/;
        # 兼容Grafana实时告警、面板推送需要的websocket连接
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        add_header Access-Control-Allow-Origin '*';
    }

    add_header Access-Control-Allow-Origin '*';
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Access-Control-Allow-Origin';
    
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

说明:proxy_pass中直接使用Docker Compose自动解析的服务名jenkins、grafana做后端地址,比自定义hostname更稳定,不需要额外配置DNS解析。

3. 重载配置生效

在docker-compose.yml所在目录执行以下命令,让所有配置生效:

# 重建Jenkins、Grafana容器加载新的环境变量
docker-compose up -d jenkins grafana
# 等待10秒让后端服务启动完成后,重载Nginx配置
sleep 10
docker-compose exec web nginx -s reload
验证结果

服务重启完成后:

  • 访问http://myapp.fr/jenkins会自动跳转到http://myapp.fr/jenkins/login?from=%2F,登录、插件管理、任务构建等所有操作的路径都会自动携带/jenkins前缀
  • 访问http://myapp.fr/grafana会自动跳转到http://myapp.fr/grafana/login,看板、告警、数据源配置等所有操作的路径都会自动携带/grafana前缀
  • 静态资源加载、接口请求不会出现跨域或404问题

内容的提问来源于stack exchange,提问作者Gati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 06:09:21