私有化部署
这是给运维 / 技术团队的文档。 普通用户不需要部署,直接使用在线服务即可:5 分钟上手。
在自有服务器上运行 Hushwork:数据库、应用、反向代理、前端与文档站。
目标架构
Nginx :443
├── / → 前端静态资源
├── /api/ → NestJS :3000
├── /socket.io/ → NestJS :3000
└── /docs/ → VitePress 静态资源
NestJS :3000(PM2 cluster)
├── MySQL
├── MongoDB(副本集)
└── Redis1. 系统要求
| 组件 | 最低 | 推荐 |
|---|---|---|
| CPU | 2 核 | 4 核 |
| 内存 | 4 GB | 8 GB |
| 磁盘 | 40 GB | 100 GB |
软件:
- Node.js 20+
- MySQL 8.0+
- MongoDB 6.0+(副本集)
- Redis 6+
- Nginx 1.24+
2. MongoDB 副本集
应用使用事务,MongoDB 必须以副本集运行。
mongod.conf
yaml
storage:
dbPath: /var/lib/mongodb
replication:
replSetName: rs0
security:
keyFile: /etc/mongo/keyfile
authorization: enabled
net:
bindIp: 127.0.0.1生成 keyFile
bash
openssl rand -base64 756 | sudo tee /etc/mongo/keyfile
sudo chmod 400 /etc/mongo/keyfile
sudo chown mongodb:mongodb /etc/mongo/keyfile初始化
bash
sudo systemctl restart mongod
mongosh --eval 'rs.initiate()'
mongosh --eval 'rs.status().ok' # 1创建应用用户
javascript
use admin
db.createUser({
user: "hushwork",
pwd: "strong-password",
roles: [{ role: "readWrite", db: "hushwork" }]
})3. 数据库准备
MySQL
sql
CREATE DATABASE hushwork CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'hushwork'@'127.0.0.1' IDENTIFIED BY 'strong-password';
GRANT ALL PRIVILEGES ON hushwork.* TO 'hushwork'@'127.0.0.1';
FLUSH PRIVILEGES;Redis
conf
requirepass strong-password
bind 127.0.0.14. 部署应用
bash
git clone https://github.com/hushwork/hushwork.git
cd hushwork/hushwork-mainend
npm ci
npm run build.env
bash
NODE_ENV=production
APP_PORT=3000
APP_ROUTE_PREFIX=api
DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=hushwork
DB_USER=hushwork
DB_PASSWORD=strong-password
MONGODB_URI=mongodb://hushwork:strong-password@127.0.0.1:27017/hushwork?authSource=hushwork&replicaSet=rs0
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=strong-password
OPENAI_API_KEY=sk-...权限:
bash
chmod 600 .env5. PM2
bash
npm install -g pm2
pm2 start ecosystem.config.js
pm2 save
pm2 startupecosystem.config.js 默认 2 实例。Socket.IO 通过 RedisIoAdapter 跨实例广播,因此 Redis 必须可用。
6. 前端
bash
npm run frontend:build
sudo mkdir -p /var/www/hushwork
sudo rsync -a --delete frontend/dist/ /var/www/hushwork/7. Nginx
nginx
server {
listen 443 ssl http2;
server_name hushwork.example.com;
ssl_certificate /etc/nginx/certs/example.crt;
ssl_certificate_key /etc/nginx/certs/example.key;
client_max_body_size 100M;
# SPA
root /var/www/hushwork;
index index.html;
location /api/ {
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_read_timeout 120s;
}
location /socket.io/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 600s;
}
location = /docs { return 301 /docs/; }
location /docs/ {
alias /var/www/hushwork-docs/;
index index.html;
try_files $uri $uri/ $uri.html =404;
error_page 404 /docs/404.html;
}
location / {
try_files $uri $uri/ /index.html;
}
}
server {
listen 80;
server_name hushwork.example.com;
return 301 https://$host$request_uri;
}bash
sudo nginx -t && sudo systemctl reload nginx8. 文档站
bash
npm run docs:build
sudo install -d -o "$USER" -g "$USER" -m 755 /var/www/hushwork-docs
npm run docs:deploydocs:deploy 执行:
bash
rsync -a --delete site/.vitepress/dist/ /var/www/hushwork-docs/验证:
bash
curl -sI https://hushwork.example.com/docs/ | head -3注意:Nginx worker 用户(如
www-data)必须能穿越/var/www下的每一级目录。如果发布目录放在/home/...下,需要额外授权,否则会返回 404 且 error log 出现Permission denied。
9. 启动验证
bash
# 应用
curl -s http://127.0.0.1:3000/api/a2a/agent-card | head
# PM2
pm2 status
# 状态层
npx jest libs/modules/src/state
# 整条业务
npm run case:reference -- --commit10. 备份与恢复
| 数据 | 命令 |
|---|---|
| MySQL | mysqldump --single-transaction hushwork > backup.sql |
| MongoDB | mongodump --uri="$MONGODB_URI" --out=/backup/mongo |
| 上传文件 | 备份 COS 或本地上传目录 |
.env | 安全保管,不进入版本库 |
恢复顺序:MySQL / Mongo → Redis(可重建)→ 应用。
11. 升级流程
bash
git pull --rebase
npm ci
npm run build
pm2 reload hushwork如涉及数据库结构变更,先执行迁移脚本。升级前:
- 备份数据库
- 在预发环境验证
- 检查
docs/ops/下的 runbook
常见故障
| 症状 | 排查 |
|---|---|
| 应用启动即退出 | pm2 logs hushwork;检查 .env 与数据库连通性 |
| MongoDB 事务报错 | rs.status() 是否 PRIMARY |
| WebSocket 断开 | Nginx 是否配置 Upgrade / Connection |
| 文档 404 | 目录权限、alias 路径、docs:deploy 是否执行 |
| 502 | 应用端口与 APP_PORT 是否一致 |
安全清单
- [ ] 数据库只监听 127.0.0.1
- [ ] Redis 设置密码
- [ ]
.env权限 600 - [ ] JWT 密钥改为环境变量注入
- [ ] HTTPS 强制跳转
- [ ] 上传大小限制
- [ ] 日志脱敏
- [ ] 定期备份与恢复演练