Nginx未转发请求至本地实例问题排查求助
访问localhost:8080/时页面显示Nginx默认页,无法转发至后端Go实例;访问localhost:8080/hello返回404错误,但直接访问localhost:5000/hello或localhost:5001/hello可正常显示"Hello World"。
当前配置
docker-compose.yml
version: '3' services: golang-instance: image: "myapi" ports: - "5000:5000" networks: - nginx_net restart: on-failure golang-instance-2: image: "myapi" ports: - "5001:5000" networks: - nginx_net restart: on-failure nginx: image: nginx ports: - "8080:80" volumes: - ./nginx.conf:/etc/nginx/conf.d/nginx.conf networks: - nginx_net restart: on-failure networks: nginx_net:
nginx.conf
upstream backend { least_conn; server golang-instance:5000; server golang-instance-2:5000; } server { listen 80; server_name localhost; location / { proxy_pass http://backend; } }
错误日志
访问localhost:8080/hello时,Nginx容器日志:
2023-09-30T18:32:28.873946632Z 172.20.0.1 - - [30/Sep/2023:18:32:28 +0000] "GET /hello HTTP/1.1" 404 555 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" "-"
已尝试的操作
- 移除
least_conn配置,无效果 - 修改Nginx的
listen端口为8080,无效果 - 调整
golang-instance-2的端口映射为5001,无效果 - 将网络改为bridge驱动,未解决问题
- 尝试三种volume映射方式:
- 映射到
/etc/nginx/nginx.conf:容器可启动,但问题依旧 - 映射到
/etc/nginx/conf.d/nginx.conf:容器可启动,但问题依旧 - 映射到
/etc/nginx/http.d/nginx.conf:容器启动失败,报错"upstream" directive is not allowed here
- 映射到
容器启动日志(option-1和option-2):
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration 2023-09-30T17:40:27.718888715Z /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ 2023-09-30T17:40:27.720393590Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 2023-09-30T17:40:27.724760049Z 10-listen-on-ipv6-by-default.sh: info: IPv6 listen already enabled 2023-09-30T17:40:27.724773299Z /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh 2023-09-30T17:40:27.725033174Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh 2023-09-30T17:40:27.731775465Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh 2023-09-30T17:40:27.736814424Z /docker-entrypoint.sh: Configuration complete; ready for start up 2023-09-30T17:40:27.759872299Z 2023/09/30 17:40:27 [warn] 1#1: conflicting server name "localhost" on 0.0.0.0:80, ignored 2023-09-30T17:40:27.759900590Z nginx: [warn] conflicting server name "localhost" on 0.0.0.0:80, ignored 2023-09-30T17:40:27.760202507Z 2023/09/30 17:40:27 [notice] 1#1: using the "epoll" event method 2023-09-30T17:40:27.760207549Z 2023/09/30 17:40:27 [notice] 1#1: nginx/1.25.2 2023-09-30T17:40:27.760209590Z 2023/09/30 17:40:27 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 2023-09-30T17:40:27.760211382Z 2023/09/30 17:40:27 [notice] 1#1: OS: Linux 5.15.49-linuxkit 2023-09-30T17:40:27.760213090Z 2023/09/30 17:40:27 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576 2023-09-30T17:40:27.761007132Z 2023/09/30 17:40:27 [notice] 1#1: start worker processes 2023-09-30T17:40:27.761015632Z 2023/09/30 17:40:27 [notice] 1#1: start worker process 22 2023-09-30T17:40:27.764749424Z 2023/09/30 17:40:27 [notice] 1#1: start worker process 23 2023-09-30T17:40:27.764774007Z 2023/09/30 17:40:27 [notice] 1#1: start worker process 24 2023-09-30T17:40:27.764776340Z 2023/09/30 17:40:27 [notice] 1#1: start worker process 25
排查建议
- 清理Nginx默认配置:官方Nginx镜像默认加载
/etc/nginx/conf.d/default.conf,该配置包含默认页的server块。进入Nginx容器删除此文件后重启:docker exec -it <nginx-container-id> rm /etc/nginx/conf.d/default.conf docker restart <nginx-container-id> - 验证生效配置:进入容器执行
nginx -T,查看完整生效配置,确认自定义server块是否存在且优先级正确。 - 调整代理配置:修改
proxy_pass为http://backend/(添加尾部斜杠),或添加proxy_set_header Host $host;,确保请求路径和头部正确传递到后端。 - 测试容器间连通性:在Nginx容器内执行
ping golang-instance验证DNS解析,再用curl http://golang-instance:5000/hello测试后端服务是否可访问。 - 开启调试日志:在Nginx配置中添加
error_log /var/log/nginx/error.log debug;,重启后查看详细日志定位转发失败原因。
内容的提问来源于stack exchange,提问作者Arthur

