Files
wecom_it_smart_desk/docs/04-运维文档/部署运维/服务器部署手册.md
T
Simon facc04aa65 chore: docs 结构整改 + compose 双目录对齐(合并重建提交)
本提交为 .git 对象库损坏后的重建提交,内容等价于原先三个本地提交
(5e2fd4c2 / 57a53c98 / 5d7e1873)的累积结果,未做任何额外改动。

一、docs 结构整改(整改 #14)
根因:重构时新结构为 untracked 文件,执行 git stash(未带 -u)未纳入,
随后 git reset 拉回 HEAD 旧 tracked 树,导致旧树复活、新旧两棵目录
树并存于 docs/,共 791 文件、双分类体系冲突。

修复动作:
- b2 同名异主题文件改名迁移保全 9 个
- C 类 39 个孤立文件按主题正确归类
- A/B1 类 222 个重复文件删除(新结构已有内容副本)
- 9 个旧独有空目录删除
- 270 处内部引用按 verified 映射改写
- 整改记录 #14 登记于 04-运维文档/部署运维

结果:docs 791 → 569 文件,顶层仅规范 8 类 + 治理文件,单树恢复。
残留:约 20 处指向从未存在文件的陈旧死链,归入独立文档卫生任务。

二、compose 双目录对齐(消除踩坑 A)
- docker-compose.yml:nginx 前端挂载全部由根目录 frontend-*/dist
  改为 src/frontend-*/dist(h5 / agent / admin / terminal)
- docker-compose.dev.yml:dev 服务 build context 与卷同步改 src/
- 效果:本地 docker compose up 不再把根目录 stale dist 挂回,
  与线上一致,分叉隐患消除(已 docker compose config 校验通过)

防复发铁律:
- 重构须提交;仓库修复须 git stash -u 或先 commit
- 新结构须 git add 并提交,避免再次 untracked 复活
- H5 改动只动 src/frontend-h5/,禁改根目录遗留 frontend-*/
2026-08-07 22:31:32 +08:00

532 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 智能IT支持服务台 — 新服务器部署手册
> **目标服务器**`10.90.5.110`(公司内网,**2026-06-15 起替代 10.80.0.136**
> **域名**`itsupport.servyou.com.cn`
> **访问方式**:通过堡垒机 `10.212.189.210:2222`(用户 `sxn`OTP 动态口令认证)
> **Docker**:已安装
> **部署方式**Docker Compose4容器:nginx + backend + postgres + redis
---
## 一、前置条件检查清单
| 条件 | 状态 | 验证命令 |
|------|------|---------|
| Linux 服务器 10.90.5.110(替代旧 10.80.0.136) | ✅ 已确认 | 2026-06-15 起使用 |
| Docker 已安装 | ✅ 已确认 | `docker --version` |
| Docker Compose V2 | 待确认 | `docker compose version` |
| 端口 80 未被占用 | 待确认 | `ss -tlnp \| grep :80` |
| DNS 解析 | 待配置 | `nslookup itsupport.servyou.com.cn` |
| 堡垒机可访问 | 待确认 | `ssh -p 2222 user@10.212.189.210` |
---
## 二、SSH 通过堡垒机连接
### 2.1 什么是堡垒机?
堡垒机(跳板机)是公司内网的安全访问入口。你不能直接 SSH 到目标服务器,必须先登录堡垒机,再从堡垒机跳转到目标服务器。OTP(One-Time Password)是指每次登录需要输入动态验证码(通常来自手机令牌 App)。
### 2.2 连接方式
**PuTTY 客户端(用户实际使用)**:
- 打开 PuTTY
- Host Name(IP 地址):`10.212.189.210`
- Port:`2222`
- Connection type:SSH
- Saved Sessions:起名(如 `wecom-bastion`)→ Save
- 点 Open
- 用户 `sxn` + 密码
- **堡垒机内再跳目标机**:
```bash
ssh sxn@10.90.5.110
```
> **OpenSSH `ssh -J` 方式不再使用**(用户已确认用 PuTTY,2026-06-15)
### 2.3 jumpserver-V2 工具(推荐)
推荐使用 jumpserver-V2 工具进行远程命令执行和文件传输。该工具一次浏览器登录后,后续通过登录缓存 cookies 免登录复用。
```bash
# 进入 skill 目录
cd C:\Users\simon\.workbuddy\skills\jumpserver-V2\scripts
# 首次登录(弹出浏览器,手动填写 OTP)
python v2_ops.py login
# 之后免登录执行命令
python v2_ops.py exec "hostname"
python v2_ops.py exec "uptime && docker ps"
# 文件上传(自动选择最优方式:<100KB 用 base64>=100KB 或 >15s 用 elFinder
python v2_ops.py upload local_file.txt /tmp/remote_file.txt
# 文件下载
python v2_ops.py download /tmp/server_file.txt ./local_file.txt
# 巡检命令(只读)
python v2_ops.py inspect
```
> **注意**:首次使用会弹出浏览器完成 JumpServer 登录和 OTP 验证,后续调用会自动复用会话(服务端 401 时自动回退重新登录)。
### 2.4 为什么不能直接用 SSH/SCP
| 方式 | 支持情况 | 原因 |
|------|---------|------|
| SSH ProxyJump | ❌ 不支持 | JumpServer 不兼容标准 SSH 代理协议 |
| SCP 直连堡垒机 | ❌ 不支持 | 需要 OTP 验证码,SCP 不支持交互式输入 |
| SSH 直连目标服务器 | ❌ 不支持 | 目标服务器仅对 JumpServer 开放 SSH 访问 |
| jumpserver-V2 | ✅ 推荐 | 自动化处理 OTP 和 Connection Token |
---
## 三、文件传输(通过堡垒机)
### 3.1 jumpserver-V2 上传(推荐)
```bash
# 上传文件到目标服务器 /tmp 目录
python v2_ops.py upload deploy.zip /tmp/deploy.zip
# 上传到其他目录
python v2_ops.py upload config.conf /opt/wecom-it-desk/config.conf
```
### 3.2 备用方案
如果 jumpserver-V2 不可用,可以考虑:
```bash
# 方式A:通过互联网可访问的存储服务(推荐)
# - 先把文件传到能通过互联网访问的存储(如:对象存储、临时文件分享服务)
# - 目标服务器通过 curl/wget 下载
# 方式B:通过堡垒机手动中转
# - 使用 jumpserver-V2 手动执行分步操作
```
---
## 四、部署步骤(完整流程)
### 步骤 1:在开发机上构建前端并打包
```bash
# 在开发机(Windows)上,进入项目根目录
cd D:\资料\03-项目开发\wecom_it_smart_desk
# 方法A:使用打包脚本(自动构建前端 + 组装 + 打包)
bash deploy-server/package.sh
# 方法B:手动构建
# H5 员工端
cd frontend-h5
npm install && npm run build
# 坐席工作台
cd ../frontend-agent
npm install && npm run build
# 手动打包(如果不用 package.sh
# 需要把 frontend-h5/dist/、frontend-agent/dist/、backend/、deploy-server/ 下的配置文件一起打包
```
打包完成后,项目根目录下会生成 `it-smart-desk-server-deploy.zip`。
### 步骤 2:上传部署包到服务器
```bash
# 在开发机上执行
scp -o "ProxyJump=sxn@10.212.189.210:2222" \
it-smart-desk-server-deploy.zip \
sxn@10.90.5.110:/tmp/
```
> 上传到 `/tmp/` 而非 `/opt/`,因为普通用户对 `/opt/` 没有写权限
### 步骤 3:登录服务器并解压
**PuTTY 登录**(见 §2.2):
- Host:`10.212.189.210`,Port:`2222`,SSH
- 堡垒机内再 `ssh sxn@10.90.5.110`
```bash
# 切换 root(普通用户对 /opt 无写权限)
sudo -i
# 移动并解压部署包
mv /tmp/it-smart-desk-server-deploy.zip /opt/
cd /opt
unzip it-smart-desk-server-deploy.zip
# 重命名目录为更简短的名称
mv it-smart-desk-server-deploy wecom-it-desk
cd wecom-it-desk
```
### 步骤 4:配置环境变量
```bash
cd /opt/wecom-it-desk
# 从模板创建 .env
cp .env.example .env
# 编辑 .env
vi .env
```
**阶段一(Mock 模式)最小配置** — 只需确认以下默认值:
```ini
# 数据库密码(默认即可,首次初始化后不可更改)
POSTGRES_PASSWORD=wecom_secret_2024
# 企微配置(阶段一 Mock 模式可以留空)
WECOM_CORP_ID=
WECOM_AGENT_ID=1000002
WECOM_SECRET=
WECOM_TOKEN=
WECOM_ENCODING_AES_KEY=
# Mock 登录(阶段一设为 true
MOCK_LOGIN_ENABLED=true
# Dify AI(暂时可以留空)
DIFY_API_URL=http://yw-dify.dc.servyou-it.com/dify2openai/v1/chat/completions
DIFY_API_KEY=
```
> **重要**`POSTGRES_PASSWORD` 首次启动时写入数据库,之后修改 `.env` 不会生效。如需修改密码,必须删除数据卷重建。
### 步骤 5:部署
```bash
cd /opt/wecom-it-desk
# 添加执行权限
chmod +x deploy.sh
# 执行部署
./deploy.sh
```
脚本会自动:
1. ✅ 检查 Docker 环境
2. ✅ 检查 .env 配置
3. ✅ 检查前端文件
4. ✅ 构建后端 Docker 镜像
5. ✅ 启动 4 个容器
6. ✅ 等待服务就绪
7. ✅ 验证部署
### 步骤 6:验证部署
```bash
# 在服务器上验证
curl http://localhost/api/health
# 应返回 {"status":"healthy"}
curl http://localhost/itdesk/
# 应返回 H5 前端 HTML
# 查看所有容器状态
docker compose ps
# 应显示 4 个容器都是 Up 状态
# 如果有容器未启动,查看日志
docker compose logs --tail 50 backend
docker compose logs --tail 50 postgres
```
### 步骤 7:配置 DNS
需要联系公司 IT 运维,在公司 DNS 上添加 A 记录:
```
itsupport.servyou.com.cn A 10.90.5.110
```
**DNS 未生效前**,可以通过本地 hosts 文件测试:
```
# Windows: C:\Windows\System32\drivers\etc\hosts
# macOS/Linux: /etc/hosts
# 添加一行:
10.90.5.110 itsupport.servyou.com.cn
```
> 注意:修改 hosts 文件后,浏览器可能有 DNS 缓存。Chrome 可访问 `chrome://net-internals/#dns` 清除缓存,或用无痕窗口测试。
### 步骤 8:浏览器验证
DNS 生效后(或配置了本地 hosts),在浏览器中访问:
| 页面 | URL | 预期结果 |
|------|-----|---------|
| H5 员工端 | `http://itsupport.servyou.com.cn/itdesk/` | 看到登录页面 |
| 坐席工作台 | `http://itsupport.servyou.com.cn/itagent/` | 看到坐席工作台 |
| API 健康检查 | `http://itsupport.servyou.com.cn/api/health` | `{"status":"healthy"}` |
**Mock 登录测试**
1. 访问 `http://itsupport.servyou.com.cn/itdesk/login`
2. 输入任意工号和姓名(如 `test001` / `测试用户`
3. 应成功登录并进入聊天页面
---
## 五、部署文件结构
### 5.1 服务器目录结构
```
/opt/wecom-it-desk/ # 项目根目录(服务器)
├── docker-compose.yml # Docker Compose 配置(4容器)
├── .env # 环境变量(已配置)
├── .env.example # 环境变量模板
├── deploy.sh # 一键部署脚本
├── nginx/
│ ├── nginx.conf # Nginx 配置(反代 + 静态文件)
│ └── ssl/ # SSL 证书
├── html/ # 前端静态文件(Nginx 挂载点)
│ ├── itdesk/ # H5 员工端 (/itdesk/)
│ ├── itagent/ # 坐席工作台 (/itagent/)
│ ├── itadmin/ # 管理后台 (/itadmin/)
│ └── itportal/ # 统一入口 (/itportal/)
└── backend/ # 后端源码(不用于生产,仅开发参考)
```
### 5.2 前端部署位置说明
| 端 | URL 路径 | 服务器目录 | Nginx 容器挂载点 |
|----|---------|-----------|----------------|
| 员工端 H5 | `/itdesk/` | `/opt/wecom-it-desk/html/itdesk/` | `/usr/share/nginx/html/itdesk` |
| 坐席工作台 | `/itagent/` | `/opt/wecom-it-desk/html/itagent/` | `/usr/share/nginx/html/itagent` |
| 管理后台 | `/itadmin/` | `/opt/wecom-it-desk/html/itadmin/` | `/usr/share/nginx/html/itadmin` |
| 统一入口 | `/itportal/` | `/opt/wecom-it-desk/html/itportal/` | `/usr/share/nginx/html/itportal` |
### 5.3 前端部署步骤
```bash
# 1. 本地构建
cd frontend-agent
npm run build
# 2. 打包(排除 node_modules
cd dist
zip -r ../agent-v1.x.zip *
# 3. 上传到服务器 /tmp/
# 4. SSH 到服务器解压
sudo rm -rf /opt/wecom-it-desk/html/itagent
sudo mkdir -p /opt/wecom-it-desk/html/itagent
sudo unzip -o /tmp/agent-v1.x.zip -d /opt/wecom-it-desk/html/itagent
# 5. 重启 Nginx 容器
docker restart wecom_it_nginx
```
---
## 六、Python 依赖管理
### 6.1 依赖说明
后端 Python 依赖在 `backend/requirements.txt` 中声明,构建 Docker 镜像时会自动安装。
**新增依赖处理流程:**
1. **开发环境**:更新 `backend/requirements.txt`
2. **打包部署**:确保 `requirements.txt` 已包含新依赖
3. **生产环境**:重建后端镜像
```bash
# 重建后端镜像(会自动安装 requirements.txt 中的所有依赖)
cd /opt/wecom-it-desk
docker compose build backend
docker compose up -d backend
```
### 6.2 常见依赖问题
| 问题 | 症状 | 解决方法 |
|------|------|---------|
| 缺少依赖 | `ModuleNotFoundError` | 重建后端镜像:`docker compose build backend` |
| 手动安装 | 容器内临时安装 | `docker exec wecom_it_backend pip install <package>` |
---
## 七、常用运维命令
在服务器上 `/opt/wecom-it-desk` 目录下执行:
| 操作 | 命令 |
|------|------|
| 查看服务状态 | `./deploy.sh status` |
| 查看后端日志 | `./deploy.sh logs` |
| 停止所有服务 | `./deploy.sh stop` |
| 重新构建后端 | `./deploy.sh rebuild` |
| 重置数据库 | `./deploy.sh reset-db` |
| 手动启动 | `docker compose up -d` |
| 手动停止 | `docker compose down` |
| 只重启后端 | `docker compose restart backend` |
| 查看数据库 | `docker exec -it wecom_it_postgres psql -U wecom -d wecom_it_desk` |
| 查看 Redis | `docker exec -it wecom_it_redis redis-cli` |
| 重载 Nginx | `docker exec wecom_it_nginx nginx -s reload` |
| 查看容器日志 | `docker compose logs --tail 50 <容器名>` |
---
## 八、升级前端
当有新的前端版本需要部署时:
```bash
# 1. 在开发机上构建新版本
cd frontend-h5 && npm run build
cd frontend-agent && npm run build
# 2. 上传到服务器(通过堡垒机)
scp -o "ProxyJump=sxn@10.212.189.210:2222" \
-r frontend-h5/dist/ \
sxn@10.90.5.110:/opt/wecom-it-desk/frontend-h5/dist/
scp -o "ProxyJump=sxn@10.212.189.210:2222" \
-r frontend-agent/dist/ \
sxn@10.90.5.110:/opt/wecom-it-desk/frontend-agent/dist/
# 3. 重载 Nginx(不需要重启整个服务)
ssh itdesk # 如果已配置 SSH 快捷方式
cd /opt/wecom-it-desk
docker exec wecom_it_nginx nginx -s reload
```
---
## 九、升级后端
```bash
# 1. 上传新代码到服务器
scp -o "ProxyJump=sxn@10.212.189.210:2222" \
-r backend/ \
sxn@10.90.5.110:/opt/wecom-it-desk/backend/
# 2. 重新构建并启动
ssh itdesk
cd /opt/wecom-it-desk
./deploy.sh rebuild
```
---
## 十、故障排查
### 后端容器一直重启
```bash
# 1. 查看容器状态
docker compose ps
# 2. 查看后端日志(最常见原因:数据库连接失败)
docker compose logs --tail 100 backend
# 3. 检查 PostgreSQL 是否健康
docker exec wecom_it_postgres pg_isready -U wecom -d wecom_it_desk
# 4. 检查 Redis 是否健康
docker exec wecom_it_redis redis-cli ping
```
### PostgreSQL 密码错误
```bash
# ⚠️ 这会清空所有数据!只有首次部署密码错误时才需要
docker compose down
docker volume rm wecom-it-desk_postgres_data
docker compose up -d
```
### H5/坐席端白屏
```bash
# 检查前端文件是否存在
docker exec wecom_it_nginx ls /usr/share/nginx/html/itdesk/
docker exec wecom_it_nginx ls /usr/share/nginx/html/itagent/
# 检查 index.html 中的 base 路径是否正确
docker exec wecom_it_nginx cat /usr/share/nginx/html/itdesk/index.html | grep /itdesk/
docker exec wecom_it_nginx cat /usr/share/nginx/html/itagent/index.html | grep /itagent/
```
### DNS 未生效
```bash
# 在服务器上验证
nslookup itsupport.servyou.com.cn
# 如果 DNS 未配置,临时用 IP 直接访问
curl http://10.90.5.110/itdesk/
curl http://10.90.5.110/api/health
```
### Mock 登录返回 401
```bash
# 1. 确认 .env 中 MOCK_LOGIN_ENABLED=true
cat /opt/wecom-it-desk/.env | grep MOCK
# 2. 检查后端日志
docker compose logs --tail 50 backend | grep mock
# 3. 直接测试 mock-login 接口
curl -X POST http://localhost/api/h5/mock-login \
-H "Content-Type: application/json" \
-d '{"employee_id":"test001","employee_name":"测试用户"}'
```
---
## 十一、HTTPS 配置(可选)
如果公司要求 HTTPS,有两种方式:
### 方式一:公司统一 SSL 终端(推荐)
```
客户端 → HTTPS → 公司SSL终端(F5/网关,公网 115.236.188.3) → HTTP → 10.90.5.110:80
```
不需要在本服务器上配置证书。联系运维配置 SSL 终端即可。
### 方式二:本机 SSL
编辑 `nginx/nginx.conf`,取消 HTTPS server 块注释,配置证书路径。
---
## 十二、部署说明
> ⚠️ NAS部署方案(itdesk.amanzac.com)已于2026年6月15日下线,现统一使用公司内网服务器部署。
| 维度 | NAS 部署(已下线) | 当前服务器部署(10.90.5.110 |
|------|---------------------------|-------------------------------|
| 容器数量 | 5个(含 cloudflared | 4个(无 cloudflared |
| 外网访问 | Cloudflare Tunnel | 公司 DNS 直连 |
| 域名 | itdesk.amanzac.com | itsupport.servyou.com.cn |
| SSL | Cloudflare 自动 | 无(内网 HTTP)或公司统一 SSL |
| 数据平台反代 | 需要(共用域名) | 不需要(独立域名) |
| 部署目录 | `/volume1/docker/wecom-it-desk` | `/opt/wecom-it-desk` |
| 文件传输 | File Station / 7z | SCP 通过堡垒机 |
---
## 十三、相关文档
| 文档 | 说明 |
|------|------|
| [堡垒机运维工具](./11-堡垒机运维工具.md) | 通过 JumpServer 自动化执行远程命令、文件上传下载 |
| [版本更新说明](./05-版本更新说明-v1.1.0-20260614.md) | 各版本功能变更记录 |
| [NAS 部署指南](./08-NAS部署指南-预生产.md) | 群晖 NAS 测试环境部署 |