269 lines
10 KiB
Markdown
269 lines
10 KiB
Markdown
|
|
# 机器人智慧服务系统 Alpha · 国内云部署说明
|
|||
|
|
|
|||
|
|
> 适用:将本项目(前端 SPA + Alpha 三服务 + nodevideo 视频服务)部署到国内云服务器
|
|||
|
|
> (阿里云 ECS / 腾讯云 CVM / 华为云 ECS,推荐 Ubuntu 22.04 LTS)。
|
|||
|
|
> 配套代码文档见 `docs/` 下设备数据字典、命令字典、状态机、联调报告等。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、系统组成与端口
|
|||
|
|
|
|||
|
|
| 组件 | 目录 / 说明 | 端口 | 数据 / 依赖 |
|
|||
|
|
|------|------------|:---:|------------|
|
|||
|
|
| 前端 SPA(React 19 + Vite) | 仓库根目录 `npm run build` → `dist/` | 开发 3001;生产由 Nginx 托管 80/443 | 通过 `env.js` 的 `baseURL` 指向后端 |
|
|||
|
|
| 设备接入服务 Alpha | `services/device-access` | **3010** | `data/devices.json` |
|
|||
|
|
| 状态服务 Alpha | `services/status` | **3020** | `data/status.json` |
|
|||
|
|
| 命令服务 Alpha | `services/command` | **3030** | `data/commands.json` |
|
|||
|
|
| 主后端(已有,非 Alpha) | 由 `env.js` 指向 | API **8081** / WS **9002** / MQTT **8083** / GeoServer **59018** | 需与前端在同一云环境且可达 |
|
|||
|
|
| 视频服务 nodevideo | 独立项目,视频管理页直连 | **9528** | SRS 录制目录 `BASE_DIR=/hdd/data/media/record/video/srs/` |
|
|||
|
|
|
|||
|
|
技术栈:Node.js + Express + 本地 JSON 文件(三服务均**不使用数据库**,数据落 `data/*.json`)。
|
|||
|
|
Alpha 三服务均 `app.use(cors())` 全开;nodevideo 亦 `app.use(cors())` 全开(跨域直连可行,但生产建议走反代同源)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 二、云服务器准备
|
|||
|
|
|
|||
|
|
1. 选购:2 vCPU / 4 GB 起(含 Cesium 三维前端,建议 4 vCPU / 8 GB);系统盘 40 GB+,数据盘按需(录像/JSON 备份)。
|
|||
|
|
2. 系统:Ubuntu 22.04 LTS(或腾讯云 TencentOS Server 3/4)。
|
|||
|
|
3. 安全组(推荐**仅暴露 22/80/443**,其它端口走 Nginx 反代):
|
|||
|
|
- 入站:22(SSH)、80(HTTP)、443(HTTPS)。
|
|||
|
|
- 出站:全通。
|
|||
|
|
- 若采用「直连各端口」方案,需额外开放 3010/3020/3030/9528/8081 等,并依赖 CORS——**不推荐生产使用**。
|
|||
|
|
4. 域名(可选但建议):国内云需 ICP 备案后才能用 80/443 绑定域名;备案期间可先用 IP + 自签/免费证书测试。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、基础环境(Ubuntu)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 1. 系统更新
|
|||
|
|
sudo apt update && sudo apt -y upgrade
|
|||
|
|
|
|||
|
|
# 2. Node.js 20 LTS(项目用 React19+Vite6,需 Node 18+)
|
|||
|
|
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
|||
|
|
sudo apt -y install nodejs
|
|||
|
|
node -v && npm -v # 期望 v20.x / v10.x
|
|||
|
|
|
|||
|
|
# 3. 进程守护 PM2(全局)
|
|||
|
|
sudo npm i -g pm2
|
|||
|
|
|
|||
|
|
# 4. 反向代理 + HTTPS
|
|||
|
|
sudo apt -y install nginx
|
|||
|
|
sudo snap install --classic certbot && sudo ln -s /snap/bin/certbot /usr/bin/certbot
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> 国内云若访问 npm 慢,可切换镜像:`npm config set registry https://registry.npmmirror.com`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 四、获取代码
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd /opt
|
|||
|
|
sudo git clone <你的仓库地址> robot-system
|
|||
|
|
sudo chown -R $USER:$USER /opt/robot-system
|
|||
|
|
cd /opt/robot-system
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> 若不用 git,可用 `scp` / 对象存储 将本地仓库打包上传解压。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 五、部署 Alpha 三服务
|
|||
|
|
|
|||
|
|
三个服务结构一致,分别安装依赖并启动。下面以 `device-access` 为例,其余两目录同理。
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 设备接入服务
|
|||
|
|
cd /opt/robot-system/services/device-access
|
|||
|
|
npm install
|
|||
|
|
pm2 start server.js --name device-access --watch
|
|||
|
|
|
|||
|
|
# 状态服务
|
|||
|
|
cd /opt/robot-system/services/status
|
|||
|
|
npm install
|
|||
|
|
pm2 start server.js --name status --watch
|
|||
|
|
|
|||
|
|
# 命令服务
|
|||
|
|
cd /opt/robot-system/services/command
|
|||
|
|
npm install
|
|||
|
|
pm2 start server.js --name command --watch
|
|||
|
|
|
|||
|
|
# 保存进程列表并实现开机自启(Linux 上 pm2 startup 可用)
|
|||
|
|
pm2 save
|
|||
|
|
pm2 startup # 按提示执行它打印的 sudo 命令(写 systemd 单元)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
验证:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
pm2 ls # 三个服务 online
|
|||
|
|
curl -s http://127.0.0.1:3010/api/devices/online/ROBOT-001 # 返回 JSON
|
|||
|
|
curl -s http://127.0.0.1:3020/health ; curl -s http://127.0.0.1:3030/health
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> 端口固定写死在 `server.js`(`PORT = 3010/3020/3030`),如需变更改文件即可。
|
|||
|
|
> 数据文件 `data/*.json` 首次启动自动创建(空数组)。部署升级时**务必备份该目录**,避免覆盖业务数据。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 六、部署前端(SPA)
|
|||
|
|
|
|||
|
|
### 6.1 配置生产后端地址
|
|||
|
|
|
|||
|
|
编辑仓库根目录 `env.js`,将 `PROD` 段改为云上实际地址(默认 `MODE=production` 时生效):
|
|||
|
|
|
|||
|
|
```js
|
|||
|
|
[ENV.PROD]: {
|
|||
|
|
baseURL: 'https://你的域名或http://云服务器IP:8081', // 主后端 API
|
|||
|
|
WS_URL: 'wss://你的域名/ws/' 或 'ws://云服务器IP:9002/ws/',
|
|||
|
|
mqtt_url: 'wss://你的域名/mqtt' 或 'ws://云服务器IP:8083/mqtt',
|
|||
|
|
geoserver_url:'https://你的域名/geoserver' 或 'http://云服务器IP:59018/geoserver'
|
|||
|
|
},
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 6.2 构建
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd /opt/robot-system
|
|||
|
|
npm install
|
|||
|
|
npm run build # 产出 dist/(MODE=production,使用 env.js 的 PROD 配置)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 6.3 视频管理页地址(重要)
|
|||
|
|
|
|||
|
|
`src/components/SystemSetting/VideoManagement.tsx` 顶部硬编码了:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
const NODEVIDEO_BASE = 'http://localhost:9528';
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
部署到云后,浏览器里的 `localhost:9528` 指向**用户本机**而非服务器,视频无法访问。二选一:
|
|||
|
|
|
|||
|
|
- **方案A(反代同源,推荐)**:改为 `const NODEVIDEO_BASE = '/nodevideo'`,并在 Nginx 配置 `location /nodevideo/ { proxy_pass http://127.0.0.1:9528/; }`。
|
|||
|
|
- **方案B(跨域直连)**:改为 `const NODEVIDEO_BASE = 'http://<云服务器IP或域名>:9528'`(nodevideo 已开 CORS,可用;但需安全组开放 9528)。
|
|||
|
|
|
|||
|
|
改完需重新 `npm run build`。
|
|||
|
|
|
|||
|
|
### 6.4 Nginx 托管 + 反代
|
|||
|
|
|
|||
|
|
```nginx
|
|||
|
|
# /etc/nginx/sites-available/robot-system
|
|||
|
|
server {
|
|||
|
|
listen 80; server_name 你的域名或IP;
|
|||
|
|
root /opt/robot-system/dist; index index.html;
|
|||
|
|
location / { try_files $uri $uri/ /index.html; } # SPA 路由回退
|
|||
|
|
|
|||
|
|
# ---- Alpha 三服务(按前端实际 API 前缀分流)----
|
|||
|
|
location /api/devices/ { proxy_pass http://127.0.0.1:3010; }
|
|||
|
|
location /api/status/ { proxy_pass http://127.0.0.1:3020; }
|
|||
|
|
location /api/commands/ { proxy_pass http://127.0.0.1:3030; }
|
|||
|
|
|
|||
|
|
# ---- nodevideo 视频(对应方案A的 /nodevideo)----
|
|||
|
|
location /nodevideo/ { proxy_pass http://127.0.0.1:9528/; }
|
|||
|
|
|
|||
|
|
# ---- 主后端(若与 Alpha 共用 /api 前缀需区分,建议独立子域或前缀)----
|
|||
|
|
location /backend/ { proxy_pass http://127.0.0.1:8081/; }
|
|||
|
|
|
|||
|
|
# WebSocket / MQTT 透传(如前端直连)
|
|||
|
|
location /ws/ { proxy_pass http://127.0.0.1:9002; proxy_http_version 1.1;
|
|||
|
|
proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> 注意:前端 `env.js` 的 `baseURL` 必须与实际访问方式一致——若走 Nginx 同源,填 `https://你的域名`(或 `/backend` 之类前缀);若主后端与 Alpha 都用 `/api` 前缀会冲突,请为二者分配不同前缀或子域。
|
|||
|
|
|
|||
|
|
启用并重载:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo ln -s /etc/nginx/sites-available/robot-system /etc/nginx/sites-enabled/
|
|||
|
|
sudo nginx -t && sudo systemctl reload nginx
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、部署 nodevideo 视频服务(9528)
|
|||
|
|
|
|||
|
|
视频管理页依赖此服务,需与前端同一云环境可达。
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd /opt/nodevideo
|
|||
|
|
npm install
|
|||
|
|
pm2 start server.js --name nodevideo
|
|||
|
|
pm2 save
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**关键路径说明**:`server.js` 中 `BASE_DIR = "/hdd/data/media/record/video/srs/"` 为 Linux 绝对路径(SRS 录制存储)。
|
|||
|
|
- 云服务器需存在该目录并挂载好录像盘;否则 `/list` 返回 `code:500 / directories:[]`,视频管理页显示为空。
|
|||
|
|
- 如路径不同,直接修改 `server.js` 的 `BASE_DIR` 后 `pm2 restart nodevideo`。
|
|||
|
|
- `PORT` 在代码里写 `30003`,但实际按你指定以 **9528** 对外(用 `PORT=9528 pm2 start server.js --name nodevideo` 或反代时统一即可)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 八、域名与 HTTPS(国内云)
|
|||
|
|
|
|||
|
|
1. **备案**:国内云使用 80/443 + 域名必须完成 ICP 备案(阿里云/腾讯云控制台申请,约 1–2 周)。
|
|||
|
|
2. **证书**:备案后用免费证书
|
|||
|
|
```bash
|
|||
|
|
sudo certbot --nginx -d 你的域名.cn
|
|||
|
|
```
|
|||
|
|
或在云控制台申请免费 DV 证书后下载,Nginx 配置 `ssl_certificate / ssl_certificate_key`。
|
|||
|
|
3. 证书自动续期:`sudo certbot renew --dry-run` 验证,certbot 默认建好 timer。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 九、开机自启(推荐 systemd)
|
|||
|
|
|
|||
|
|
PM2 在 Linux 可用 `pm2 startup`(写 systemd 单元)实现开机拉起全部 `pm2 save` 的进程,最省事。
|
|||
|
|
若偏好纯 systemd,可为每个服务写一个 unit(示例 `device-access.service`):
|
|||
|
|
|
|||
|
|
```ini
|
|||
|
|
[Unit]
|
|||
|
|
Description=Device Access Service Alpha
|
|||
|
|
After=network.target
|
|||
|
|
|
|||
|
|
[Service]
|
|||
|
|
WorkingDirectory=/opt/robot-system/services/device-access
|
|||
|
|
ExecStart=/usr/bin/node server.js
|
|||
|
|
Restart=always
|
|||
|
|
User=www-data
|
|||
|
|
Environment=NODE_ENV=production
|
|||
|
|
|
|||
|
|
[Install]
|
|||
|
|
WantedBy=multi-user.target
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo systemctl enable --now device-access
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 十、运维与备份
|
|||
|
|
|
|||
|
|
- **日志**:`pm2 logs <name>`;或 journald `journalctl -u device-access -f`。
|
|||
|
|
- **数据备份**:三服务的 `data/*.json` 是业务数据,定时备份:
|
|||
|
|
```bash
|
|||
|
|
tar czf /backup/alpha-data-$(date +%F).tgz /opt/robot-system/services/*/data/
|
|||
|
|
```
|
|||
|
|
- **录像备份**:nodevideo 的 `/hdd/.../srs` 目录按磁盘策略归档。
|
|||
|
|
- **升级流程**:拉新代码 → `npm install` → `npm run build`(前端)→ `pm2 restart <name>`;升级前先备份 `data/`。
|
|||
|
|
- **回滚**:保留上一版 `dist/` 与 `services`,出问题时 `pm2 restart` 旧版本或 git checkout。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 十一、快速检查清单
|
|||
|
|
|
|||
|
|
- [ ] 云服务器 Ubuntu 22.04,安全组仅开 22/80/443(反代方案)
|
|||
|
|
- [ ] Node 20 LTS + npm + pm2 + nginx 已装
|
|||
|
|
- [ ] Alpha 三服务 `pm2 ls` 均 online,端口 3010/3020/3030 监听 127.0.0.1
|
|||
|
|
- [ ] 前端 `npm run build` 成功,`dist/` 由 Nginx 托管
|
|||
|
|
- [ ] `env.js` 的 `PROD` 段 baseURL/WS/MQTT/GeoServer 已改为云地址
|
|||
|
|
- [ ] 视频管理页 `NODEVIDEO_BASE` 已改为 `/nodevideo` 或云地址并重新 build
|
|||
|
|
- [ ] nodevideo :9528 已起,`BASE_DIR` 存在且有录像;`/list` 能返回通道
|
|||
|
|
- [ ] Nginx 反代规则就位,`nginx -t` 通过
|
|||
|
|
- [ ] 域名已备案,HTTPS 证书已配置并自动续期
|
|||
|
|
- [ ] `pm2 save` + `pm2 startup` 完成,重启服务器后服务自动拉起
|
|||
|
|
- [ ] `data/*.json` 备份任务已配置
|