# 智能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 Compose（4容器：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)
# 登录成功后：
ssh sxn@10.90.5.110
```

### 2.3 配置 SSH 快捷方式（推荐）

在开发机上编辑 `~/.ssh/config`，添加以下内容，以后只需要 `ssh itdesk` 即可：

```
# 堡垒机
Host bastion
    HostName 10.212.189.210
    Port 2222
    User sxn

# 智能IT支持服务台服务器
Host itdesk
    HostName 10.90.5.110
    User sxn
    ProxyJump bastion
```

> **堡垒机用户名为 `sxn`，已填入下方命令中**

之后只需：
```bash
ssh itdesk          # 自动通过堡垒机跳转
scp file itdesk:/opt/  # 文件传输也会自动走堡垒机
```

---

## 三、文件传输（通过堡垒机）

### 3.1 SCP 传输（推荐小文件/单次传输）

```bash
# 上传单个文件
scp -o "ProxyJump=sxn@10.212.189.210:2222" \
    it-smart-desk-server-deploy.zip \
    sxn@10.90.5.110:/opt/

# 如果已配置 ~/.ssh/config：
scp it-smart-desk-server-deploy.zip itdesk:/opt/
```

### 3.2 大文件传输优化

部署包可能较大（含后端源码 + 前端产物），如果 SCP 速度慢，可以先传到堡垒机再转：

```bash
# 步骤1：传到堡垒机
scp -P 2222 it-smart-desk-server-deploy.zip sxn@10.212.189.210:/tmp/

# 步骤2：SSH 到堡垒机
ssh -p 2222 sxn@10.212.189.210

# 步骤3：从堡垒机传到目标服务器
scp /tmp/it-smart-desk-server-deploy.zip sxn@10.90.5.110:/opt/
```

---

## 四、部署步骤（完整流程）

### 步骤 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. 应成功登录并进入聊天页面

---

## 五、部署文件结构

```
/opt/wecom-it-desk/
├── docker-compose.yml     # Docker Compose 配置（4容器）
├── .env                   # 环境变量（已配置）
├── .env.example           # 环境变量模板
├── deploy.sh              # 一键部署脚本
├── README.md              # 本手册
├── nginx/
│   └── nginx.conf         # Nginx 配置（反代 + 静态文件）
├── backend/
│   ├── Dockerfile          # 后端镜像构建文件
│   ├── requirements.txt    # Python 依赖
│   └── app/               # 后端源代码
├── frontend-h5/
│   └── dist/              # H5 员工端构建产物
└── frontend-agent/
    └── dist/              # 坐席工作台构建产物
```

---

## 六、常用运维命令

在服务器上 `/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 部署的差异

| 维度 | NAS 部署（10.80.0.136,已下线） | 新服务器部署（10.90.5.110,2026-06-15 起） |
|------|---------------------------|-------------------------------|
| 容器数量 | 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 通过堡垒机 |
