React + Vite 项目使用 PM2 部署测试环境全流程指南(附踩坑指南)

302 阅读2分钟

🛠 React + Vite 项目使用 PM2 部署测试环境全流程指南(附 Docker 对比)

0526更新 - 配置开机自启服务 发现服务器重启之后,原本部署的一些前端服务不可见了,需要补充开机自启动的配置....

1. 保存当前运行的进程列表

pm2 save

这会把当前进程列表保存到 ~/.pm2/dump.pm2 文件。

2. 设置 PM2 自启动(系统服务)

pm2 startup

这条命令会输出一条类似下面的命令:

sudo env PATH=$PATH:/your/path pm2 startup systemd -u your_user --hp /home/your_user

复制粘贴并运行这条命令,它会设置 PM2 为 systemd 的开机服务。

3. 再次保存进程

pm2 save

总结:设置完一次即可生效,每次新增进程后记得运行一次 pm2 save

🧭 背景介绍

在之前的测试环境部署中,我们使用的是 Docker 容器,部署流程如下:

  1. 手动登录服务器;
  2. 拉取 Git 仓库最新代码;
  3. 执行 runtest.sh 脚本进行打包并构建镜像;
  4. 停止旧容器,启动新容器;

虽然这种方式有较强的隔离性与可控性,但对轻量前端项目来说显得流程稍重。因此本次我们采用更灵活的 PM2 + Node 方式来部署前端打包产物,减少部署链路复杂度。

🧱 环境准备(服务器)

1. 安装 Node.js(推荐使用 nvm)

// 注意根据服务器类型替换命令
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install 18
nvm use 18

2. 安装 PM2

npm install -g pm2

🧳 本地打包流程

1. 打测试包

npm run build:test

这会生成一个 dist/ 文件夹,里面包含打包好的静态资源。

2. 将 dist 上传到你的服务器目录下

scp -r dist/ xx@xx.xx.xx.xx:/home/xx/web-server/

或者写个脚本upload.sh以后每次更新执行脚本即可

npm run build:test && scp -r dist/ xx@xx.xx.xx.xx:/home/xx/web-server/

🧩 服务器配置

1.新建 app.js(PM2 启动入口)

const express = require('express');
const path = require('path');
const app = express();

// 配置跨域(可选)
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'http://your-frontend-domain');
  res.header('Access-Control-Allow-Credentials', 'true');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

// 静态资源配置
app.use('/', express.static(path.join(__dirname, 'dist')));

// 动态路由配置
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});

const port = yourport;
app.listen(port, () => {
  console.log(`App listening on port ${port}`);
});

🚀 使用 PM2 启动服务

pm2 start app.js --name web-server
pm2 logs web-server
pm2 startup
pm2 save

📎 初次部署踩坑记录

❌ 路由 404 报错

项目中使用了动态路由,需要在appjs中需添加 app.get('*') 映射到 index.html

❌ CORS 报错

res.header('Access-Control-Allow-Origin', 'http://your-frontend-domain');
res.header('Access-Control-Allow-Credentials', 'true');

❌ # TypeError: Missing parameter name at 2: git.new/pathToRegex…

控制台报错[pathToRegexpError],页面始终加载不出来,以为是路由配置的问题,就去检索了所有的routerkey配置发现没啥问题,google了一下发现github上有类似问题的做法是给express降级,express5版本可能会遇见这个问题,Downgrade to 4.21.2之后就没有问题了,可以正常加载 (参考链接:github.com/expressjs/e…

🔁 与 Docker 部署方式对比

项目Docker 部署PM2 + Node 部署
操作流程拉取代码 + 构建镜像本地打包上传
资源占用高,包含镜像+容器低,仅 Node 环境
运行隔离性高,运行于独立容器中,运行在主机上
可维护性容器可快速替换静态文件需手动更新
热更新重启容器pm2 reload web-server
适用场景后端服务、隔离环境静态站点测试环境

✅ 小结

PM2 部署更轻便、灵活,适合测试环境;Docker 更适合正式环境部署,保障一致性与隔离性。