根本原因是Nginx默认absolute_redirect on强制生成含协议和端口的绝对重定向URL,而它只识别容器内端口(如80),不知宿主机映射端口(如8080),导致Location头错误;必须在server块中同时配置absolute_redirect off和port_in_redirect off,并确保server_name明确或设为"",才能生成相对路径Location实现正确跳转。
在 Docker 容器中用 Nginx 提供静态服务时,访问 /admin 自动跳转到 /admin/ 却报 404 或跳错地址,根本原因不是路径写错,而是 Nginx 默认开启 absolute_redirect on,强行拼出带协议和端口的绝对 URL——而它只认容器内端口(如 80),完全不知道宿主机映射的是 8080 或 9279,结果生成的 Location 头要么丢端口、要么写错端口,浏览器根本打不开。
关键配置必须加在 server 块里
只在 http 块或 location 块设 absolute_redirect off 不生效。必须确保该指令作用于实际处理请求的 server 上:
- 显式写
server_name(如server_name example.com;),避免靠默认匹配 - 若走 IP 直连或 Host 头不固定,可用
server_name "";匹配空 Host - 确认
listen端口与容器暴露端口逻辑一致(比如容器内监听 80,宿主机映射到 8080)
配套关闭 port_in_redirect
absolute_redirect off 解决了拼协议和域名的问题,但 port_in_redirect on(默认值)仍可能往 Location 里硬塞端口。两者要一起关:
Red Panda AI
AI文本生成图像
下载
-
absolute_redirect off;→ 返回Location: /admin/(相对路径) -
port_in_redirect off;→ 防止 Nginx 在绝对重定向时擅自加 :80 或 :8080 - 两个都关,浏览器才真正按当前地址上下文解析跳转,不依赖 Nginx 猜端口
alias 场景下特别容易触发
用 alias 做静态目录映射时(比如 alias /usr/share/nginx/html/app/;),Nginx 对末尾斜杠敏感:访问 /app 会自动 301 跳转到 /app/。这个跳转就是 absolute_redirect 的典型作用点:
- 不关它 → 生成
Location: http://host:80/app/(暴露容器端口)或http://host/app/(丢掉宿主机端口) - 关掉后 → 生成
Location: /app/,浏览器自动补全当前 URL 的协议、域名、端口,跳转自然正确
验证是否生效的小技巧
改完配置 reload 后,用 curl 检查响应头最直接:
-
curl -I http://localhost:8080/admin(宿主机端口) - 看返回是否有
Location: /admin/—— 是相对路径就对了 - 如果还是
Location: http://...,说明配置没落到对应 server 块,或被更高优先级配置覆盖