使用Docker+Nginx搭建Express/React服务时后端连接失败排查
问题:Nginx无法通过反向代理连接Docker后端服务
问题描述
使用Express、React、Docker和Nginx搭建服务时,遇到Nginx无法连接后端的问题。本地直接访问localhost:8080/api可正常连接,但通过localhost/api访问时提示连接拒绝。
相关配置文件
nginx.conf
upstream frontend { server 127.0.0.1:3000; } upstream backend { server 127.0.0.1:8080; } server { listen *:80; server_name localhost; # ignore cache frontend location ~* (service-worker\.js)$ { add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; expires off; proxy_no_cache 1; } location / { root /var/www/frontend; try_files $uri $uri/ /index.html?q=$uri&$args; } location /api { proxy_pass http://backend; proxy_redirect off; 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-Host $server_name; } }
error.log
2023/07/15 18:33:41 [notice] 1#1: using the "epoll" event method 2023/07/15 18:33:41 [notice] 1#1: nginx/1.23.1 2023/07/15 18:33:41 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6) 2023/07/15 18:33:41 [notice] 1#1: OS: Linux 5.10.76-linuxkit 2023/07/15 18:33:41 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576 2023/07/15 18:33:41 [notice] 1#1: start worker processes 2023/07/15 18:33:41 [notice] 1#1: start worker process 24 2023/07/15 18:33:41 [notice] 1#1: start worker process 25 2023/07/15 18:33:41 [notice] 1#1: start worker process 26 2023/07/15 18:33:41 [notice] 1#1: start worker process 27 2023/07/15 18:33:41 [notice] 1#1: start worker process 28 2023/07/15 18:34:28 [error] 25#25: *2 directory index of "/var/www/frontend/" is forbidden, client: 172.18.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost" 2023/07/15 18:34:28 [error] 25#25: *2 rewrite or internal redirection cycle while internally redirecting to "/index.html", client: 172.18.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost", referrer: "http://localhost/" 2023/07/15 18:34:35 [error] 24#24: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET /api/ HTTP/1.1", upstream: "http://127.0.0.1:8080/api/", host: "localhost" 2023/07/15 18:34:51 [error] 24#24: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.18.0.1, server: localhost, request: "GET /api/ HTTP/1.1", upstream: "http://127.0.0.1:8080/api/", host: "localhost"
docker-compose.yml
version: "3.8" volumes: build_folder: null services: frontend: build: context: ./wordPad_front args: API_URL: "*" environment: - REACT_APP_BACKEND_URL=http://localhost:8000 volumes: - ./wordPad_front/:/frontend - build_folder:/frontend/build tty: true nginx: build: ./wordPad_nginx ports: - 80:80 volumes: - build_folder:/var/www/frontend - ./wordPad_nginx/log:/var/log/nginx depends_on: - frontend backend: build: ./wordPad_back command: "node index.js" ports: - "8080:8080" depends_on: postgre: condition: service_healthy postgre: build: ./wordPad_db volumes: - ./wordPad_db/data:/data ports: - "5432:5432" env_file: - "./wordPad_db/.env" healthcheck: test: ["CMD-SHELL", "pg_isready", "-d", "db_prod"] interval: 30s timeout: 60s retries: 5 start_period: 80s adminer: image: adminer ports: - 6638:8080
问题分析
- 核心连接问题:从error.log的
connect() failed (111: Connection refused)错误可知,Nginx尝试连接127.0.0.1:8080失败。在Docker Compose环境中,每个容器都是独立的网络节点,127.0.0.1指向Nginx容器自身,而非宿主机或backend服务容器,因此无法访问到后端服务。 - 路径转发问题:当前
location /api的proxy_pass配置未加末尾斜杠,会将/api路径完整传递给后端,即转发请求为http://127.0.0.1:8080/api/,若后端路由未对应此路径,可能引发额外问题。 - 前端静态文件问题:error.log中出现目录索引禁止和重定向循环错误,是因为
location /未指定默认索引文件,且try_files的参数可能引发循环。
解决方案
1. 修正Nginx后端地址配置
修改nginx.conf中的upstream backend配置,将127.0.0.1:8080替换为Docker Compose的服务名backend:8080,利用Docker内部DNS解析到后端容器:
upstream backend { server backend:8080; }
2. 调整proxy_pass路径
根据后端路由配置,选择合适的proxy_pass格式:
- 若后端服务的API路由以
/api开头,保持现有配置即可; - 若后端服务的API路由在根路径(如
/),则在proxy_pass末尾添加斜杠,将/api后的路径转发到后端根路径:
location /api { proxy_pass http://backend/; # 其他proxy配置保持不变 }
3. 修复前端静态文件问题
在location /块中添加index index.html;,并简化try_files参数:
location / { root /var/www/frontend; index index.html; try_files $uri $uri/ /index.html; }
4. 修正React后端地址
修改docker-compose.yml中frontend的REACT_APP_BACKEND_URL为/api,让前端请求通过Nginx反向代理转发,而非直接访问未开放的端口:
environment: - REACT_APP_BACKEND_URL=/api
后续处理方向
- 修改配置后,重启Nginx容器:
docker-compose restart nginx,测试localhost/api是否正常访问; - 确认后端Express服务监听地址为
0.0.0.0(而非127.0.0.1),确保容器外部可访问; - 在Nginx容器内测试连通性:
docker-compose exec nginx curl http://backend:8080/api,验证是否能直接访问后端服务; - 检查后端服务日志,确认是否收到Nginx转发的请求。
内容的提问来源于stack exchange,提问作者roku
相关产品推荐
相关产品推荐

