You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

问题分析

  1. 核心连接问题:从error.log的connect() failed (111: Connection refused)错误可知,Nginx尝试连接127.0.0.1:8080失败。在Docker Compose环境中,每个容器都是独立的网络节点,127.0.0.1指向Nginx容器自身,而非宿主机或backend服务容器,因此无法访问到后端服务。
  2. 路径转发问题:当前location /api的proxy_pass配置未加末尾斜杠,会将/api路径完整传递给后端,即转发请求为http://127.0.0.1:8080/api/,若后端路由未对应此路径,可能引发额外问题。
  3. 前端静态文件问题: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 22:15:10