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

Docker容器Nginx部署React应用:无法加载App.tsx问题求助

问题描述

本地执行npm run dev运行正常的React+Vite+TS项目,通过多阶段Dockerfile构建镜像后,容器运行无报错,但访问localhost时仅能看到public目录下的空白index.html,无法加载TSX编译后的内容。

相关配置文件

Dockerfile

# Step 1: Use an official Node runtime as a parent image
FROM node:20.10.0 as build

# Step 2: Set the working directory in the container
RUN mkdir /app
WORKDIR /app

# Step 3: Copy the package.json files and install dependencies
COPY package-lock.json ./
COPY package.json ./
RUN npm install --verbose
RUN npm set audit false

# Step 4: Copy the rest of your app's source code
COPY . /app

# Step 5: Build your app
RUN npm run build

# Stage 2: Serve the application with Nginx
FROM nginx:alpine

# Step 6: Copy build artifacts from the 'build' stage to the Nginx directory
COPY --from=build /app/build /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d/default.conf

# Step 7: Expose port 80 for Nginx
EXPOSE 80

# Step 8: Start Nginx
CMD ["nginx", "-g", "daemon off;"]

Nginx配置文件

nginx.conf

events {
    # Event-driven configuration
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    # Include server configurations
    include /etc/nginx/conf.d/*.conf;

    # Further http configurations
}

default.conf

server {
    # Listen on port 80 for incoming connections
    listen 80;

    # Define the root directory where your files are located
    # This should be the path to your built React application
    root /usr/share/nginx/html;

    # Specify the file to serve as index
    index index.html;

    # Handle Single Page Application (SPA) routing:
    # Attempt to serve any requested file or route, fall back to index.html if not found
    location / {
        try_files $uri $uri/ /index.html;
    }

    # Custom error pages (optional)
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        internal;
    }
}

容器运行日志

2024/01/06 13:06:51 [notice] 1#1: start worker process 32
2024/01/06 13:06:51 [notice] 1#1: start worker process 33
2024/01/06 13:06:51 [notice] 1#1: start worker process 34
2024/01/06 13:06:51 [notice] 1#1: start worker process 35
2024/01/06 13:06:51 [notice] 1#1: start worker process 36
2024/01/06 13:06:51 [notice] 1#1: start worker process 37
172.17.0.1 - - [06/Jan/2024:13:07:15 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows 
NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" "-"
    172.17.0.1 - - [06/Jan/2024:13:07:19 +0000] "\x16\x03\x01\x02,\x01\x00\x02(\x03\x03\xF3P\xD9\xB0C\xB6\x9D1\x9D\x14\xE3\xBFr\x95\x1B\x22_\xFD8I\xA7\xE2\x16#DNy\x03\x5C\xED\x9F\x19 \xB61\xB2\x89C\xAA\xCA=\x8E\xA2\x18\x8B\x9Cs\x12f\x9C\xBD\xF9\x80J\xD2@eV;\xCA$i\xE8L\xDE\x00 \xFA\xFA\x13\x01\x13\x02\x13\x03\xC0+\xC0/\xC0,\xC00\xCC\xA9\xCC\xA8\xC0\x13\xC0\x14\x00\x9C\x00\x9D\x00/\x005\x01\x00\x01\xBF\xCA\xCA\x00\x00\x00\x0B\x00\x02\x01\x00\x00" 400 157 "-" "-" "-"
    172.17.0.1 - - [06/Jan/2024:13:07:19 +0000] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03-:\xE1\x8B/\xAA\xA0k^\xBC \xCF\xBA\x19\xF0\xFC\x18\xE5)r]\x9CZ42\xB3\xB7\xA3\xFB\x95`\x82 yL\xE0\x1DW[\x9ENwp\x97L\xC5\xE8[p6\xA6\xA7N^\xAB\xBE\xE8L\xD3\x0E\x83\x87 \xAD-\x00 jj\x13\x01\x13\x02\x13\x03\xC0+\xC0/\xC0,\xC00\xCC\xA9\xCC\xA8\xC0\x13\xC0\x14\x00\x9C\x00\x9D\x00/\x005\x01\x00\x01\x93\xFA\xFA\x00\x00\x00" 400 157 "-" "-" "-"
    172.17.0.1 - - [06/Jan/2024:13:07:19 +0000]

public/index.html内容

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="monetag" content="5a02f84c329734f784dc0af09b7ae775">
    <meta charset="UTF-8" />
    <link rel="icon" type="image/png" href="../favicon192.png" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React + TS 2</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

容器内/usr/share/nginx/html目录文件列表

/usr/share/nginx/html/ls -ltr
drwxr-xr-x    2 root     root          4096 Jan  6 09:54 source-map-url
drwxr-xr-x   19 root     root          4096 Jan  6 10:07 @webassemblyjs
drwxr-xr-x   24 root     root          4096 Jan  6 10:07 @types
drwxr-xr-x    4 root     root          4096 Jan  6 10:07 enhanced-resolve
drwxr-xr-x    3 root     root          4096 Jan  6 10:07 loader-runner
drwxr-xr-x    2 root     root          4096 Jan  6 10:07 infer-owner
drwxr-xr-x    4 root     root          4096 Jan  6 10:07 webpack-sources
drwxr-xr-x   10 root     root          4096 Jan  6 10:07 webpack
drwxr-xr-x    4 root     root          4096 Jan  6 10:07 watchpack
drwxr-xr-x    3 root     root          4096 Jan  6 10:07 tapable
drwxr-xr-x    3 root     root          4096 Jan  6 10:07 serialize-javascript
drwxr-xr-x    3 root     root          4096 Jan  6 10:07 schema-utils
-rwxr-xr-x    1 root     root          1738 Jan  6 10:12 package.json
-rwxr-xr-x    1 root     root        903386 Jan  6 10:12 package-lock.json
-rwxr-xr-x    1 root     root           201 Jan  6 10:37 vite.config.ts
-rwxr-xr-x    1 root     root           758 Jan  6 11:36 Dockerfile
-rwxr-xr-x    1 root     root           398 Jan  6 11:50 index.html
-rwxr-xr-x    1 root     root             4 Jan  6 11:52 COMMIT_EDITMSG
-rwxr-xr-x    1 root     root          8181 Jan  6 11:52 index
-rwxr-xr-x    1 root     root            41 Jan  6 11:52 ORIG_HEAD
drwxr-xr-x    3 root     root          4096 Jan  6 11:55 logs
-rwxr-xr-x    1 root     root           103 Jan  6 13:01 FETCH_HEAD
-rwxr-xr-x    1 root     root           168 Jan  6 13:03 nginx.conf
/usr/share/nginx/html

问题排查与解决

核心问题定位

从容器内目录列表可以明显看到:/usr/share/nginx/html下存放的是项目根目录的所有文件(包括node_modules依赖、Dockerfile、源码文件等),而非React项目构建后的静态产物。这说明构建阶段的产物没有正确复制到Nginx的服务目录中。

具体解决步骤

1. 修正Vite构建产物路径

Vite默认执行npm run build后,产物会输出到dist目录,而非Dockerfile中写的build目录。修改Dockerfile中复制构建产物的路径:

# Stage 2中修改复制路径
COPY --from=build /app/dist /usr/share/nginx/html/

如果你的项目自定义了构建输出目录,可查看vite.config.ts中的build.outDir配置,对应修改上述路径。

2. 验证本地构建是否正常

先在本地执行npm run build,检查项目根目录是否生成了dist(或自定义的输出)文件夹,且文件夹内包含index.html和assets目录(存放编译后的JS/CSS资源)。如果构建失败,需先修复TS语法错误、依赖缺失等问题。

3. 清理Docker缓存重新构建

使用无缓存构建命令,避免旧缓存影响:

docker build --no-cache -t react-app .

运行容器后,再次检查/usr/share/nginx/html目录,应只包含构建后的静态文件,而非项目源码。

4. 修正index.html中的资源路径

public/index.html里的favicon路径../favicon192.png是错误的,构建后favicon会被复制到dist根目录,应改为:

<link rel="icon" type="image/png" href="/favicon192.png" />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 02:27:03