NGINX反向代理多端口Docker应用出现重定向404问题求助
问题
部署了三个Docker容器:NGINX反向代理容器 + 两个Web应用容器,全部置于自定义网络中。端口映射配置:代理监听8080,app1监听54401,app2监听54402。直接访问三个服务(http://localhost:8080、http://localhost:54401、http://localhost:54402)均能正常显示各自的标识页面。
预期通过http://localhost:8080/app1和http://localhost:8080/app2访问对应应用,但实际访问时会被重定向到http://localhost/app1并出现404错误,app2情况相同,且NGINX日志无报错信息。
相关配置文件如下:
代理的default.conf
upstream app1 { server app1:54401; } upstream app2 { server app2:54402; } server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; } location /app1/ { proxy_pass http://app1/; } location /app2/ { proxy_pass http://app2/; } }
app1的配置
server { listen 54401; location / { root /usr/share/nginx/html; index index.html index.htm; } }
app2的配置
server { listen 54402; location / { root /usr/share/nginx/html; index index.html index.htm; } }
Docker Compose文件
services: app1: image: docker.io/nginx:stable-alpine container_name: app1 restart: unless-stopped volumes: - ./app1/html:/usr/share/nginx/html - ./app1/config:/etc/nginx/conf.d ports: - "54401:54401" networks: - test_network app2: image: docker.io/nginx:stable-alpine container_name: app2 volumes: - ./app2/html:/usr/share/nginx/html - ./app2/config:/etc/nginx/conf.d ports: - "54402:54402" networks: - test_network proxy: image: docker.io/nginx:stable-alpine container_name: proxy volumes: - ./proxy/html:/usr/share/nginx/html - ./proxy/config:/etc/nginx/conf.d - ./proxy/logs:/var/log/nginx ports: - "8080:80" networks: - test_network networks: test_network: {}
解决方案
问题根源是反向代理未传递正确的请求头,导致后端app1/app2的NGINX生成重定向URL时丢失了外部访问端口(8080),同时页面内的绝对路径资源也会指向错误地址。需要做以下调整:
1. 更新代理的default.conf,添加代理请求头与重定向规则
在/app1/和/app2/的location块中补充配置,确保后端服务能感知外部访问的正确地址:
location /app1/ { proxy_pass http://app1/; # 传递包含端口的Host头,让后端生成正确的重定向URL proxy_set_header Host $host:$server_port; # 传递客户端真实地址与协议信息 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; # 强制替换后端返回的重定向地址,确保前缀与端口正确 proxy_redirect http://app1/ http://$host:$server_port/app1/; } location /app2/ { proxy_pass http://app2/; proxy_set_header Host $host:$server_port; 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; proxy_redirect http://app2/ http://$host:$server_port/app2/; }
2. 处理页面内的绝对路径资源(可选)
如果app1/app2的HTML页面中使用了绝对路径(比如<link href="/css/style.css">),浏览器会直接请求http://localhost:8080/css/style.css而非带前缀的路径,导致404。可以通过两种方式解决:
- 方式一:修改后端NGINX配置适配前缀
以app1为例,修改其配置文件:
同时更新代理的server { listen 54401; location /app1/ { root /usr/share/nginx/html; index index.html index.htm; # 移除URL中的/app1前缀,匹配实际文件路径 rewrite ^/app1/(.*)$ /$1 break; } }proxy_pass配置(去掉末尾斜杠):location /app1/ { proxy_pass http://app1; # 保留之前的请求头配置 proxy_set_header Host $host:$server_port; ... proxy_redirect http://app1/app1/ http://$host:$server_port/app1/; } - 方式二:修改HTML使用相对路径
将页面内的绝对路径改为相对路径(比如把/css/style.css改为css/style.css),避免依赖根路径。
内容的提问来源于stack exchange,提问作者mcwyrm
相关产品推荐
相关产品推荐

