
前言
在现代前端开发中,React已经成为最流行的框架之一。然而,很多开发者在将React应用部署到生产环境时都会遇到各种问题:路由刷新404、静态资源缓存策略不当、性能优化不足等。本文将详细介绍如何在腾讯云轻量应用服务器上,通过宝塔面板完美部署React应用。
架构概览
在深入部署细节之前,让我们先了解整个部署架构:
#mermaid-svg-qrfobVP18PvvVp7N {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-qrfobVP18PvvVp7N .error-icon{fill:#552222;}#mermaid-svg-qrfobVP18PvvVp7N .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qrfobVP18PvvVp7N .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-qrfobVP18PvvVp7N .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qrfobVP18PvvVp7N .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qrfobVP18PvvVp7N .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qrfobVP18PvvVp7N .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qrfobVP18PvvVp7N .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qrfobVP18PvvVp7N .marker.cross{stroke:#333333;}#mermaid-svg-qrfobVP18PvvVp7N svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qrfobVP18PvvVp7N .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-qrfobVP18PvvVp7N .cluster-label text{fill:#333;}#mermaid-svg-qrfobVP18PvvVp7N .cluster-label span{color:#333;}#mermaid-svg-qrfobVP18PvvVp7N .label text,#mermaid-svg-qrfobVP18PvvVp7N span{fill:#333;color:#333;}#mermaid-svg-qrfobVP18PvvVp7N .node rect,#mermaid-svg-qrfobVP18PvvVp7N .node circle,#mermaid-svg-qrfobVP18PvvVp7N .node ellipse,#mermaid-svg-qrfobVP18PvvVp7N .node polygon,#mermaid-svg-qrfobVP18PvvVp7N .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qrfobVP18PvvVp7N .node .label{text-align:center;}#mermaid-svg-qrfobVP18PvvVp7N .node.clickable{cursor:pointer;}#mermaid-svg-qrfobVP18PvvVp7N .arrowheadPath{fill:#333333;}#mermaid-svg-qrfobVP18PvvVp7N .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qrfobVP18PvvVp7N .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qrfobVP18PvvVp7N .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-qrfobVP18PvvVp7N .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-qrfobVP18PvvVp7N .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qrfobVP18PvvVp7N .cluster text{fill:#333;}#mermaid-svg-qrfobVP18PvvVp7N .cluster span{color:#333;}#mermaid-svg-qrfobVP18PvvVp7N div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qrfobVP18PvvVp7N :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}服务器内部PM2 Node服务 3000端口React静态文件React应用用户访问80/443端口Nginx反向代理直接返回静态资源处理SPA路由
这种架构既利用了Nginx的高性能静态文件服务,又通过Node.js服务处理动态路由,实现了最佳的性能和用户体验。
环境准备
1. 服务器要求
- 腾讯云轻量应用服务器(带宝塔面板)
- 最低配置:1核2GB(可根据应用规模调整)
- 操作系统:CentOS 7.6+ / Ubuntu 18.04+
2. 本地开发环境
- Node.js 14+
- React 16+
- 项目打包工具(Webpack/Vite)
第一步:本地React应用打包
在部署之前,我们需要先在本地将React应用打包为生产版本。
打包配置优化
在打包前,建议在package.json中添加以下配置以确保静态资源路径正确:
{
"name": "my-react-app",
"version": "1.0.0",
"homepage": ".",
"scripts": {
"build": "react-scripts build",
"build:analyze": "BUNDLE_ANALYZE=true npm run build"
}
}
执行打包命令
# 进入项目目录
cd /path/to/your/react-app
# 安装依赖(如尚未安装)
npm install
# 执行打包命令
npm run build
打包完成后,项目根目录会生成build文件夹,包含所有静态资源文件:
build/
├── static/
│ ├── js/
│ ├── css/
│ └── media/
├── index.html
├── favicon.ico
└── manifest.json
第二步:服务器环境配置
1. 创建网站站点
登录宝塔面板,按照以下步骤创建站点:
- 域名:您的服务器IP或已绑定的域名(如:124.222.216.48)
- 根目录:/www/wwwroot/react-app(可自定义)
- PHP版本:选择「纯静态」
- FTP:不创建
- 数据库:不创建

2. 防火墙端口配置
确保服务器防火墙开放必要端口:
# 在宝塔面板「安全」页面添加端口规则
80端口 – HTTP访问
443端口 – HTTPS访问(可选)

第三步:文件上传与目录结构
上传打包文件
最终目录结构
/www/wwwroot/react-app/
├── static/
│ ├── js/
│ │ ├── main.abc123.js
│ │ └── main.abc123.js.map
│ ├── css/
│ │ ├── main.def456.css
│ │ └── main.def456.css.map
│ └── media/
│ └── icons.ghi789.svg
├── index.html
├── favicon.ico
├── manifest.json
└── asset-manifest.json
第四步:使用PM2管理React服务
虽然React构建产物是静态文件,但为了更好的路由支持和生产环境特性,我们使用Node.js服务来运行。
1. 安装PM2
通过SSH连接到服务器并执行:
# 全局安装PM2和serve
npm install -g pm2 serve
2. 使用PM2启动React应用
# 切换到网站根目录
cd /www/wwwroot/react-app
# 使用PM2启动服务
pm2 serve . 3000 –spa –name "react-app"
# 设置开机自启
pm2 save
pm2 startup
关键参数说明:
- serve . 3000:在当前目录启动服务,端口3000
- –spa:单页应用模式,所有路由回退到index.html
- –name "react-app":指定进程名称
3. 验证服务状态
# 查看PM2进程列表
pm2 list
# 查看服务日志
pm2 logs react-app
# 在服务器本地测试服务
curl http://localhost:3000


第五步:Nginx反向代理配置
这是最关键的一步,我们需要配置Nginx将80端口的请求代理到3000端口的React服务。
第一步:

第二步:

完整的Nginx配置
server
{
listen 80;
listen [::]:80;
server_name 124.222.216.48;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/react-app;
# SSL证书验证配置(保持原样)
#CERT-APPLY-CHECK–START
include /www/server/panel/vhost/nginx/well-known/124.222.216.48.conf;
#CERT-APPLY-CHECK–END
# 注释掉PHP相关配置
# include enable-php-00.conf;
# 注释掉默认错误页
# error_page 404 /404.html;
# error_page 502 /502.html;
# URL重写规则
include /www/server/panel/vhost/rewrite/124.222.216.48.conf;
# 禁止访问敏感文件
location ~ ^/(\\.user.ini|\\.htaccess|\\.git|\\.env|\\.svn|\\.project|LICENSE|README.md)
{
return 404;
}
# SSL证书验证目录
location ~ \\.well-known{
allow all;
}
# 静态资源长期缓存
location ~* \\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|map)$ {
expires 1y;
add_header Cache-Control "public, immutable";
try_files $uri $uri/ @proxy;
}
# HTML文件不缓存
location ~* \\.(html)$ {
expires -1;
add_header Cache-Control "no-cache, must-revalidate";
try_files $uri $uri/ @proxy;
}
# 核心代理配置
location @proxy {
proxy_pass http://127.0.0.1:3000;
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-Proto $scheme;
proxy_buffering off;
}
# 所有路由处理
location / {
try_files $uri $uri/ @proxy;
}
access_log /www/wwwlogs/124.222.216.48.log;
error_log /www/wwwlogs/124.222.216.48.error.log;
}
配置关键点解析
#mermaid-svg-RY8Rr4227e62j1ha {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-RY8Rr4227e62j1ha .error-icon{fill:#552222;}#mermaid-svg-RY8Rr4227e62j1ha .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RY8Rr4227e62j1ha .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-RY8Rr4227e62j1ha .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RY8Rr4227e62j1ha .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RY8Rr4227e62j1ha .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RY8Rr4227e62j1ha .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RY8Rr4227e62j1ha .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RY8Rr4227e62j1ha .marker.cross{stroke:#333333;}#mermaid-svg-RY8Rr4227e62j1ha svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RY8Rr4227e62j1ha .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-RY8Rr4227e62j1ha .cluster-label text{fill:#333;}#mermaid-svg-RY8Rr4227e62j1ha .cluster-label span{color:#333;}#mermaid-svg-RY8Rr4227e62j1ha .label text,#mermaid-svg-RY8Rr4227e62j1ha span{fill:#333;color:#333;}#mermaid-svg-RY8Rr4227e62j1ha .node rect,#mermaid-svg-RY8Rr4227e62j1ha .node circle,#mermaid-svg-RY8Rr4227e62j1ha .node ellipse,#mermaid-svg-RY8Rr4227e62j1ha .node polygon,#mermaid-svg-RY8Rr4227e62j1ha .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RY8Rr4227e62j1ha .node .label{text-align:center;}#mermaid-svg-RY8Rr4227e62j1ha .node.clickable{cursor:pointer;}#mermaid-svg-RY8Rr4227e62j1ha .arrowheadPath{fill:#333333;}#mermaid-svg-RY8Rr4227e62j1ha .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RY8Rr4227e62j1ha .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RY8Rr4227e62j1ha .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-RY8Rr4227e62j1ha .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-RY8Rr4227e62j1ha .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RY8Rr4227e62j1ha .cluster text{fill:#333;}#mermaid-svg-RY8Rr4227e62j1ha .cluster span{color:#333;}#mermaid-svg-RY8Rr4227e62j1ha div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RY8Rr4227e62j1ha :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}静态文件存在静态文件不存在用户请求Nginx处理直接返回静态资源代理到React服务返回缓存的文件PM2 React服务 3000端口返回SPA页面用户收到响应
- 静态资源:1年缓存
- HTML文件:不缓存
第六步:验证与测试
1. 基础功能测试
# 测试首页访问
curl http://124.222.216.48
# 测试API代理(如果有后端API)
curl http://124.222.216.48/api/health
2. React路由测试
在浏览器中测试以下场景:
- ✅ 直接访问首页
- ✅ 通过导航跳转到子页面
- ✅ 刷新子页面(应不出现404)
- ✅ 浏览器前进/后退功能
3. 性能测试
# 使用ab进行简单压力测试
ab -n 1000 -c 10 http://124.222.216.48/
高级优化配置
1. Gzip压缩配置
在Nginx配置中添加:
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;
2. 安全头配置
# 添加安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
3. PM2集群模式(多核CPU)
# 使用集群模式利用多核CPU
pm2 delete react-app
pm2 start npm –name "react-app" -i max — run serve:prod
故障排除
常见问题及解决方案
| 白屏 | 静态资源路径错误 | 检查homepage配置,确保为. |
| 路由404 | SPA配置缺失 | 确认Nginx配置中有try_files和@proxy |
| 静态资源加载失败 | 文件权限问题 | 执行chown -R www:www /www/wwwroot/react-app |
| 502 Bad Gateway | PM2服务未启动 | 检查pm2 list,重启服务 |
日志检查步骤
检查Nginx错误日志:
tail -f /www/wwwlogs/124.222.216.48.error.log
检查PM2服务日志:
pm2 logs react-app
检查系统资源:
top
free -h
df -h
部署流程图总结
#mermaid-svg-3rHTRk4toNTz9eVm {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3rHTRk4toNTz9eVm .error-icon{fill:#552222;}#mermaid-svg-3rHTRk4toNTz9eVm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3rHTRk4toNTz9eVm .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-3rHTRk4toNTz9eVm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3rHTRk4toNTz9eVm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3rHTRk4toNTz9eVm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3rHTRk4toNTz9eVm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3rHTRk4toNTz9eVm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3rHTRk4toNTz9eVm .marker.cross{stroke:#333333;}#mermaid-svg-3rHTRk4toNTz9eVm svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3rHTRk4toNTz9eVm .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-3rHTRk4toNTz9eVm .cluster-label text{fill:#333;}#mermaid-svg-3rHTRk4toNTz9eVm .cluster-label span{color:#333;}#mermaid-svg-3rHTRk4toNTz9eVm .label text,#mermaid-svg-3rHTRk4toNTz9eVm span{fill:#333;color:#333;}#mermaid-svg-3rHTRk4toNTz9eVm .node rect,#mermaid-svg-3rHTRk4toNTz9eVm .node circle,#mermaid-svg-3rHTRk4toNTz9eVm .node ellipse,#mermaid-svg-3rHTRk4toNTz9eVm .node polygon,#mermaid-svg-3rHTRk4toNTz9eVm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3rHTRk4toNTz9eVm .node .label{text-align:center;}#mermaid-svg-3rHTRk4toNTz9eVm .node.clickable{cursor:pointer;}#mermaid-svg-3rHTRk4toNTz9eVm .arrowheadPath{fill:#333333;}#mermaid-svg-3rHTRk4toNTz9eVm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3rHTRk4toNTz9eVm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3rHTRk4toNTz9eVm .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-3rHTRk4toNTz9eVm .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-3rHTRk4toNTz9eVm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3rHTRk4toNTz9eVm .cluster text{fill:#333;}#mermaid-svg-3rHTRk4toNTz9eVm .cluster span{color:#333;}#mermaid-svg-3rHTRk4toNTz9eVm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3rHTRk4toNTz9eVm :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}持续集成自动构建代码推送自动部署健康检查本地开发React应用打包上传到服务器PM2启动Node服务配置Nginx反向代理测试各项功能监控与优化
结语
通过本文的详细指南,您应该已经成功在腾讯云轻量应用服务器上部署了React应用。这种部署方案具有以下优势:
现在,您的React应用已经准备好面向用户提供服务了!如果有任何问题,欢迎在评论区讨论。
以我之思,借AI之力!


