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

Docker容器中Nginx部署React应用访问报连接重置问题

问题根因

你的配置存在3处核心错误,直接导致访问3000端口时连接被重置:

  • Nginx路由规则冲突:location /块中同时配置了try_files(用于返回前端静态文件)和proxy_pass(用于转发后端请求),Nginx执行规则时优先匹配try_files,找不到对应文件就直接回退返回index.html,完全不会执行后面的代理逻辑。同时你没有给前端静态资源、后端接口做路径拆分,所有请求都走根路径规则,代理配置等于无效。
  • Nginx启动模式不符合容器运行要求:你用service nginx start命令启动Nginx时,Nginx默认会以守护进程模式在后台运行,主进程完成fork后就会退出,加上容器内1号进程的管控机制,会导致Nginx端口监听状态不稳定,甚至进程提前退出,外部请求进来就会直接被重置连接。
  • 启动脚本逻辑有漏洞:脚本里所有服务启动都没有做就绪校验,Deno服务直接放到后台运行,最后用wait -n只要有任意一个后台进程退出就会终止整个容器,很容易出现Nginx还没完成端口绑定、服务还没完全启动,脚本就进入等待状态,外部访问直接失败。
修复步骤

1. 调整Nginx配置,拆分路由规则

替换nginx.conf为如下内容,将/api前缀的请求转发到Deno后端,其余路径返回React静态资源:

server {
    listen 3000;
    server_name localhost;
    root /usr/share/nginx/html;
    index index.html;

    # 后端接口转发
    location /api/ {
        proxy_pass http://127.0.0.1:5000/;
        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_http_version 1.1;
    }

    # 前端静态资源返回
    location / {
        try_files $uri $uri/ /index.html;
    }
}

注意:修改后需要把React项目里的后端接口请求统一加上/api前缀,否则请求会命中前端路由规则返回index.html,无法正常调用后端。

2. 修正Dockerfile依赖安装

你当前的安装命令缺少端口检测依赖,把Dockerfile里第一行安装依赖的RUN命令修改为:

RUN apt-get update && apt-get install -y curl unzip sudo nginx netcat-openbsd

这里新增的netcat-openbsd用于后续脚本检测Deno服务是否启动就绪。

3. 重写启动脚本,保证服务稳定运行

替换script.sh为如下内容,去掉不必要的sudo命令,增加服务就绪校验,最后让Nginx以前台模式运行作为容器主进程:

#!/bin/bash
set -e

# 初始化PostgreSQL数据库
service postgresql start
su - postgres -c "psql -U postgres -d postgres -c \"alter user postgres with password 'postgres';\""
su - postgres -c "psql postgres -c \"create database db;\""

# 初始化数据表,后台启动Deno服务
cd /app/backend
deno run --unstable --allow-env --allow-net database/seeds.ts
denon start &

# 等待Deno服务端口就绪
while ! nc -z 127.0.0.1 5000; do
  sleep 0.5
done

# 关闭Nginx守护进程模式,以前台方式启动,作为容器主进程
nginx -g "daemon off;"

可选优化

你最开始提到要使用Docker多阶段构建,但当前Dockerfile把Node.js、编译依赖、PostgreSQL服务、Nginx、Deno全装在同一个镜像里,最终镜像体积会超过1G,完全没有用到多阶段构建的优势。可以拆分构建阶段:

  • 第一阶段用官方Node镜像编译React前端,只输出build目录的静态产物
  • 第二阶段用官方Deno镜像缓存后端依赖,编译后端代码
  • 最终运行阶段只保留Nginx、Deno运行时、PostgreSQL必要组件,不需要安装Node、build-essential这类编译期依赖,镜像体积可以压缩到300M以内,构建速度和运行安全性都会提升。

内容的提问来源于stack exchange,提问作者Slim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:12:22