部署踩坑总结文档
> **文档目的**: 记录项目部署过程中遇到的所有问题和解决方案,为后续部署提供参考和警示。
>
> **文档版本**: 1.0.0
> **最后更新**: 2026-03-02
> **适用环境**: V10SP3 / CentOS / Ubuntu Linux
-–
##
目录
1. [环境变量加载问题](#1-环境变量加载问题)
2. [前端API地址硬编码问题](#2-前端api地址硬编码问题)
3. [Electron崩溃导致服务终止](#3-electron崩溃导致服务终止)
4. [嵌入服务部署问题](#4-嵌入服务部署问题)
5. [服务器环境配置问题](#5-服务器环境配置问题)
6. [文件同步不完整问题](#6-文件同步不完整问题)
7. [离线部署问题](#7-离线部署问题)
8. [服务管理问题](#8-服务管理问题)
9. [网络连接问题](#9-网络连接问题)
10. [部署检查清单](#10-部署检查清单)
-–
## 1. 环境变量加载问题
### 问题描述
**严重程度**:
高
服务器上配置了 `.env` 文件,但后端服务无法读取环境变量,导致:
- 远程模型配置未生效
- 系统回退到本地 Ollama 模式
- Dashboard 显示 “远程模型未配置”
### 根本原因
`server.js` 和 `research-service.js` 文件开头没有加载 `dotenv` 配置:
```javascript
//
错误:没有加载 dotenv
const express = require(‘express’);
// … 其他代码
// process.env.LLM_BASE_URL = undefined
// process.env.LLM_API_KEY = undefined
```
### 解决方案
在文件最开头添加 dotenv 配置加载:
```javascript
//
正确:在所有其他代码之前加载 dotenv
const path = require(‘path’);
require(‘dotenv’).config({ path: path.resolve(__dirname, ‘../.env’) });
const express = require(‘express’);
// … 其他代码
```
### 涉及文件
| 文件 | 状态 |
|------|------|
| `electron/server.js` |
已修复 |
| `electron/research-service.js` |
已修复 |
### 预防措施
1. **代码规范**: 所有需要读取环境变量的文件,必须在开头加载 `dotenv`
2. **启动检查**: 添加环境变量验证逻辑
```javascript
// 添加环境变量验证
function validateEnv() {
const required = [‘LLM_BASE_URL’, ‘LLM_API_KEY’];
const missing = required.filter(key => !process.env[key]);
if (missing.length > 0) {
console.warn(\`⚠️ 缺少环境变量: ${missing.join(', ')}\`);
}
}
```
-–
## 2. 前端API地址硬编码问题
### 问题描述
**严重程度**:
高
前端所有 API 请求硬编码为 `http://localhost:3001`,导致:
- 从其他机器访问服务器时无法连接后端
- `Failed to fetch` 错误
- 所有 API 调用失败
### 根本原因
前端代码直接使用硬编码地址:
```typescript
//
错误:硬编码 localhost
const response = await fetch(‘http://localhost:3001/api/health’);
```
### 解决方案
创建动态 API 地址配置模块:
```typescript
// src/config/api.ts
export const getApiBaseUrl = (): string => {
if (typeof window !== ‘undefined’) {
const hostname = window.location.hostname;
const protocol = window.location.protocol;
if (hostname === 'localhost' || hostname === '127.0.0.1') {
return 'http://localhost:3001';
}
return \`${protocol}//${hostname}:3001\`;
}
return ‘http://localhost:3001’;
};
export const API_BASE_URL = getApiBaseUrl();
```
使用方式:
```typescript
//
正确:使用动态地址
import { API_BASE_URL } from ‘../config/api’;
const response = await fetch(`${API_BASE_URL}/api/health`);
```
### 涉及文件
| 文件 | 修改内容 |
|------|----------|
| `src/config/api.ts` | 新建 - API地址配置模块 |
| `src/pages/Dashboard.tsx` | 替换硬编码地址 |
| `src/pages/LiteratureManager.tsx` | 替换硬编码地址 |
| `src/pages/ReviewGenerator.tsx` | 替换硬编码地址 |
| `src/pages/SettingsPage.tsx` | 替换硬编码地址 |
| `src/pages/DirectionSuggester.tsx` | 替换硬编码地址 |
| `src/pages/QAPage.tsx` | 替换硬编码地址 |
### 预防措施
1. **禁止硬编码**: 所有 API 地址必须通过配置模块获取
2. **代码审查**: 检查所有 `fetch` 调用是否使用配置模块
3. **ESLint 规则**: 添加规则检测硬编码的 localhost 地址
-–
## 3. Electron崩溃导致服务终止
### 问题描述
**严重程度**:
高
Electron 应用崩溃后,后端和前端服务也被终止,导致:
- Web 端无法访问
- API 服务中断
- 用户看到 `Failed to fetch` 错误
### 根本原因
启动脚本设计缺陷:
```javascript
//
错误:Electron 退出时关闭所有服务
electronProcess.on(‘exit’, (code) => {
console.log(‘Electron exited, shutting down…’);
backendProcess.kill();
frontendProcess.kill();
process.exit(0);
});
```
当 Electron 因安装损坏或其他原因崩溃时,会触发退出事件,导致所有服务被终止。
### 解决方案
修改启动脚本,区分正常退出和异常崩溃:
```javascript
//
正确:Electron 崩溃不影响后端服务
electronProcess.on(‘exit’, (code) => {
if (code === 0) {
console.log('Electron 正常退出,关闭所有服务...');
backendProcess.kill();
frontendProcess.kill();
} else {
console.warn('⚠️ Electron 异常退出 (Crash),后端服务继续运行');
console.warn('请使用浏览器访问 http://localhost:5173');
}
});
```
### 涉及文件
| 文件 | 状态 |
|------|------|
| `scripts/start-all.js` |
已修复 |
### 预防措施
1. **服务解耦**: 后端服务应该独立运行,不依赖 Electron
2. **Systemd 服务**: 使用 systemd 管理后端服务,确保持续运行
3. **进程监控**: 添加进程监控和自动重启机制
-–
## 4. 嵌入服务部署问题
### 问题描述
**严重程度**:
高
嵌入服务未包含在部署脚本中,导致:
- RAG 功能无法使用
- 向量检索失败
- QA 问答功能异常
### 根本原因
部署脚本 `server-deploy.sh` 没有包含嵌入服务的安装和配置。
### 解决方案
#### 4.1 创建嵌入服务文件
```python
# embedding_service.py
from flask import Flask, request, jsonify
from sentence_transformers import SentenceTransformer
import os
app = Flask(_name_)
model_name = os.environ.get(‘EMBED_MODEL’, ‘all-MiniLM-L6-v2’)
model = SentenceTransformer(model_name)
@app.route(‘/health’, methods=[‘GET’])
def health():
return jsonify({'status': 'ok', 'model': model_name})
@app.route(‘/api/embeddings’, methods=[‘POST’])
def embed():
data = request.get_json()
text = data.get('prompt', '')
embedding = model.encode(text).tolist()
return jsonify({'embedding': embedding})
if _name_ == ‘_main_’:
port = int(os.environ.get('EMBED_PORT', 11435))
app.run(host='0.0.0.0', port=port)
```
#### 4.2 创建 Systemd 服务
```ini
# /etc/systemd/system/embedding.service
[Unit]
Description=Private Embedding Service (Sentence Transformers)
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/trae-project
Environment=“EMBED_MODEL=all-MiniLM-L6-v2”
Environment=“EMBED_PORT=11435”
Environment=“HF_HOME=/opt/trae-project/.model_cache”
ExecStart=/usr/bin/python3 /opt/trae-project/embedding_service.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
#### 4.3 更新部署脚本
```bash
# 添加到 server-deploy.sh
echo “安装嵌入服务依赖…”
pip3 install sentence-transformers flask
echo “配置嵌入服务…”
cp deploy/embedding.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable embedding
systemctl start embedding
```
### 预防措施
1. **完整部署清单**: 确保部署脚本包含所有必要服务
2. **依赖检查**: 部署后验证所有服务状态
3. **离线部署包**: 准备完整的离线部署包,包含所有依赖
-–
## 5. 服务器环境配置问题
### 问题描述
**严重程度**:
中
服务器环境配置不完整,导致:
- Node.js 版本不兼容
- Python 依赖缺失
- 防火墙端口未开放
### 解决方案
#### 5.1 Node.js 安装
```bash
# 使用 NodeSource 安装 Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# 验证安装
node -v # 应显示 v20.x.x
npm -v
```
#### 5.2 Python 环境配置
```bash
# 安装 Python 和 pip
sudo apt install -y python3 python3-pip python3-venv
# 安装必要依赖
pip3 install sentence-transformers flask chromadb
```
#### 5.3 防火墙配置
```bash
# 开放必要端口
sudo firewall-cmd --add-port=3001/tcp --permanent # 后端服务
sudo firewall-cmd --add-port=11435/tcp --permanent # 嵌入服务
sudo firewall-cmd --add-port=8000/tcp --permanent # ChromaDB
sudo firewall-cmd --reload
# 验证配置
sudo firewall-cmd --list-all
```
### 环境配置清单
| 项目 | 要求 | 验证命令 |
|------|------|----------|
| Node.js | >= 18.x | `node -v` |
| npm | >= 9.x | `npm -v` |
| Python | >= 3.8 | `python3 --version` |
| pip | 最新版 | `pip3 --version` |
| 内存 | >= 4GB | `free -h` |
| 磁盘 | >= 20GB | `df -h` |
-–
## 6. 文件同步不完整问题
### 问题描述
**严重程度**:
中
同步脚本只同步后端文件,不同步前端文件,导致:
- 服务器运行的是旧版本前端代码
- 修复后问题仍然存在
- 调试困难
### 根本原因
同步脚本 `sync-to-server.js` 只包含后端文件:
```javascript
//
不完整:只同步后端文件
const filesToSync = [
{ local: ‘electron/server.js’, remote: ‘server.js’ },
{ local: ‘electron/research-service.js’, remote: ‘research-service.js’ }
];
```
### 解决方案
更新同步脚本,包含所有必要文件:
```javascript
//
完整:同步所有必要文件
const filesToSync = [
// 后端文件
{ local: ‘electron/server.js’, remote: ‘electron/server.js’ },
{ local: ‘electron/research-service.js’, remote: ‘electron/research-service.js’ },
// 前端文件
{ local: ‘src/config/api.ts’, remote: ‘src/config/api.ts’ },
{ local: ‘src/pages/Dashboard.tsx’, remote: ‘src/pages/Dashboard.tsx’ },
{ local: ‘src/pages/QAPage.tsx’, remote: ‘src/pages/QAPage.tsx’ },
{ local: ‘src/pages/ReviewGenerator.tsx’, remote: ‘src/pages/ReviewGenerator.tsx’ },
{ local: ‘src/pages/LiteratureManager.tsx’, remote: ‘src/pages/LiteratureManager.tsx’ },
{ local: ‘src/pages/SettingsPage.tsx’, remote: ‘src/pages/SettingsPage.tsx’ },
{ local: ‘src/pages/DirectionSuggester.tsx’, remote: ‘src/pages/DirectionSuggester.tsx’ },
// 配置文件
{ local: ‘.env’, remote: ‘.env’ }
];
```
## 7. 离线部署问题
### 问题描述
**严重程度**:
中
服务器无法访问互联网,导致:
- Python 依赖无法安装
- 模型文件无法下载
- 部署失败
### 解决方案
#### 7.1 准备离线部署包
```powershell
# 在有网络的机器上下载依赖
pip download -r requirements-embedding.txt -d pip_packages_linux/
# 下载模型
python -c “from sentence_transformers import SentenceTransformer; SentenceTransformer(‘all-MiniLM-L6-v2’)”
# 打包模型缓存
tar -czvf models-cache.tar.gz ~/.cache/huggingface/
```
#### 7.2 离线安装
```bash
# 在服务器上安装依赖
pip3 install --no-index --find-links=pip_packages_linux/ -r requirements-embedding.txt
# 解压模型缓存
tar -xzvf models-cache.tar.gz -C ~/
```
#### 7.3 离线部署包结构
```
embedding-deploy-package/
├── embedding_service.py # 服务主程序
├── requirements-embedding.txt # 依赖清单
├── pip_packages_linux/ # 离线安装包 (~900MB)
│ ├── torch-2.4.1-*.whl
│ ├── sentence_transformers-*.whl
│ └── … (36个whl文件)
├── deploy/
│ ├── offline-deploy.sh # 离线部署脚本
│ └── embedding.service # systemd配置
└── README.txt # 部署说明
```
-–
## 8. 服务管理问题
### 问题描述
**严重程度**:
中
服务管理不规范,导致:
- 服务启动顺序错误
- 服务依赖关系混乱
- 故障恢复困难
### 解决方案
#### 8.1 创建统一启动脚本
```bash
#!/bin/bash
# start-all.sh - 统一启动脚本
echo “启动嵌入服务…”
systemctl start embedding
sleep 5
echo “启动主服务…”
systemctl start trae-project
echo “验证服务状态…”
curl -s http://localhost:11435/health && echo "
Embedding OK"
curl -s http://localhost:3001/api/health && echo "
Backend OK"
```
#### 8.2 配置服务依赖
```ini
[Unit]
Description=Trae Backend Service
After=network.target embedding.service
Requires=embedding.service
```
#### 8.3 服务管理命令
```bash
# 查看服务状态
systemctl status trae-project embedding
# 查看服务日志
journalctl -u trae-project -f
journalctl -u embedding -f
# 重启服务
systemctl restart trae-project
# 停止所有服务
systemctl stop trae-project embedding
```
-–
## 9. 网络连接问题
### 问题描述
**严重程度**:
中
网络连接问题导致:
- 远程模型无法访问
- 服务间通信失败
- API 请求超时
### 排查步骤
#### 9.1 检查网络连通性
#### 9.2 常见网络问题
| 问题 | 原因 | 解决方案 |
|------|------|----------|
| Connection refused | 服务未启动 | 启动对应服务 |
| Connection timeout | 防火墙阻止 | 开放端口 |
| Name resolution failed | DNS问题 | 检查DNS配置 |
| SSL certificate error | 证书问题 | 检查证书或使用HTTP |
-–
## 10. 部署检查清单
### 部署前检查
- [ ] 服务器网络连通性正常
- [ ] SSH 可以正常登录
- [ ] Node.js v18+ 已安装
- [ ] Python 3.8+ 已安装
- [ ] 防火墙端口已开放(3001, 11435, 8000)
- [ ] 远程 LLM 服务可访问
- [ ] 磁盘空间充足(至少 20GB)
### 部署后验证
- [ ] 后端服务运行正常 (`curl http://localhost:3001/api/health\`)
- [ ] 嵌入服务运行正常 (`curl http://localhost:11435/health\`)
- [ ] 前端可以访问 (`curl http://localhost:5173`)
- [ ] 远程模型连接正常
- [ ] QA 问答功能正常
- [ ] 综述生成功能正常
- [ ] 文献上传功能正常
##
更新记录
| 日期 | 版本 | 更新内容 |
|------|------|----------|
| 2026-03-02 | 1.0.0 | 初始版本,整理所有部署问题 |