Nginx代理无法转发至Docker容器?技术求助
问题排查:Nginx反向代理后端接口返回404
环境配置
Docker网络创建命令
docker network create my-network
Backend的docker-compose.yml
version: '3' services: my-backend: image: my-backend ports: - "8080:8080" networks: - my-network networks: my-network: driver: bridge external: true
Frontend的docker-compose.yml
version: '3' services: my-frontend: image: my-frontend ports: - "4200:80" networks: - my-network networks: my-network: driver: bridge external: true
问题现象
- Frontend容器内通过
curl http://my-backend:8080/somepath可正常访问后端接口 - 浏览器访问
http://localhost:4200能正常打开前端应用,http://localhost:4200/example转发正常 - 访问
http://localhost:4200/backend/deployment-info时Nginx返回404,但直接访问http://localhost:8080/deployment-info正常
补充配置与调试信息
修改Nginx配置,添加反向代理规则:
location /backend { resolver 127.0.0.11; # 同时在http和server段添加了该行 set $backend http://my-backend:8080; proxy_pass $backend; }
使用nginx-debug调试,关键日志显示:
my-frontend_1 | 2022/11/08 12:56:02 [debug] 30#30: *5 http request line: "GET /backend/deployment-info HTTP/1.1" my-frontend_1 | 2022/11/08 12:56:02 [debug] 30#30: *5 http uri: "/backend/deployment-info" my-frontend_1 | 2022/11/08 12:56:02 [debug] 30#30: *5 test location: "backend" my-frontend_1 | 2022/11/08 12:56:02 [debug] 30#30: *5 using configuration "/backend" my-frontend_1 | 2022/11/08 12:56:02 [debug] 30#30: *5 http script value: "http://my-backend:8080" my-frontend_1 | 2022/11/08 12:56:02 [debug] 30#30: *5 http script set $backend my-frontend_1 | 2022/11/08 12:56:02 [debug] 30#30: *5 http upstream resolve: "/backend/deployment-info?" my-frontend_1 | 2022/11/08 12:56:02 [debug] 30#30: *5 name was resolved to 172.19.0.2 my-frontend_1 | 2022/11/08 12:56:02 [debug] 30#30: *5 connect to 172.19.0.2:8080, fd:13 #7 my-frontend_1 | 2022/11/08 12:56:02 [debug] 30#30: *5 http proxy status 404 "404 Not Found"
已验证curl 172.19.0.2:8080/deployment-info可正常访问后端接口。
问题原因与解决方案
从日志可见,Nginx把请求/backend/deployment-info原封不动转发给了后端,但后端实际接口路径是/deployment-info,而非/backend/deployment-info,因此后端返回404。
调整Nginx配置,去掉转发路径中的/backend前缀,有两种写法可选:
- 带变量的写法(保留resolver配置):
location /backend { resolver 127.0.0.11; set $backend http://my-backend:8080; rewrite ^/backend(.*)$ $1 break; proxy_pass $backend; }
- 更简洁的写法(利用路径自动替换):
location /backend/ { resolver 127.0.0.11; proxy_pass http://my-backend:8080/; }
注意location和proxy_pass末尾的斜杠,它们会自动把请求中的/backend/替换为/,转发后的路径变为/deployment-info,后端即可正确处理。
内容的提问来源于stack exchange,提问作者Searles
相关产品推荐
相关产品推荐

