阿里云公网核心节点 (aliyun) 部署与更新手册
该目录保存阿里云公网节点的所有组件部署配置、服务定义与更新操作说明。
重要说明:
- FreeSWITCH 软交换中心在阿里云上已经安装并稳定运行,无需再次安装或重新部署。
- 阿里云主要负责:
- Web 前端静态站点更新:
callflow-webpage、callout-webpage两端 SPA 产物与文档站托管- 业务编排服务更新:
callflow-esl二进制、配置更新与 systemd 托管;- 公网入口与安全终结:Nginx (HTTPS/WSS 终结、反代、录音与静态托管);
- 穿透与中继基础服务:FRPS (
7000) 与 coTURN (3478/31000-31040)。
1. 目录结构与职责
text
deploy/aliyun/
├── nginx/ # 公网 Nginx 反向代理、HTTPS SSL 终结与前端 SPA 静态托管
│ ├── ai-voice-public.conf
│ └── README.md # server 块清单、反代规则、缓存与安全约定、排障速查
├── callflow-esl/ # FreeSWITCH Outbound ESL 业务编排服务
│ ├── callflow-esl.config.toml
│ └── callflow-esl.service
├── freeswitch/ # 核心 SIP 软交换中心配置参考树 (已有,无需重复部署)
│ ├── autoload_configs/ # modules / verto / local_stream / acl / switch 等模块级配置
│ ├── dialplan/ # default.xml:AI 业务 50xx、分机 10xx、会议 30xx、回音 9196
│ ├── directory/ # 分机 1000-1030
│ ├── sip_profiles/ # internal.xml:SIP 15321 (防运营商5060封锁)、WS 5066、WSS 7443
│ ├── tls/ # 样例证书,禁止直接复用
│ └── README.md # 仓库侧变更清单与生产比对结论、上线约束
├── frp/ # FRP 反向代理穿透服务端 (FRPS)
│ ├── frps.toml
│ └── frps.service
├── coturn/ # WebRTC 5G 软电话 STUN/TURN 穿透服务
│ ├── turnserver.conf.example
│ ├── coturn.service
│ └── README.md
└── docs-site/ # 官方文档站点 (ai-voice.wangijun.com) Nginx 配置
├── nginx.conf
├── nginx-http-bootstrap.conf
└── README.md2. 服务与端口拓扑
| 服务 | 监听端口 / 地址 | 部署路径 | 说明 |
|---|---|---|---|
| Nginx | 0.0.0.0:80, 443 | /etc/nginx/ | 8 域名 HTTPS/WSS 终结、静态 SPA 托管与 API 反代(规则详见 nginx/README.md) |
| callflow-webpage | 前端静态资源 | /usr/app/webpage/callflow-webpage/dist/spa | 呼叫流程可视化前端 SPA (callflow.wangijun.com) |
| callout-webpage | 前端静态资源 | /usr/app/webpage/callout-webpage/dist/spa | 智能外呼与坐席管理前端 SPA(含「AI 策略中心」,callout.wangijun.com) |
| docs-site | 文档站静态资源 | /usr/app/ai-voice-docs/current | 平台技术文档站点 (ai-voice.wangijun.com) |
| callflow-esl | 127.0.0.1:9911 (ESL)127.0.0.1:9912 (HTTP) | /usr/app/callflow-esl/ | Outbound ESL 呼叫流程控制服务 |
| FreeSWITCH | 172.21.38.245:5066 (WS) / 7443 (WSS) / 8081+8082 (Verto)12015 (inbound ESL), 30000-30199/UDP | /usr/local/freeswitch/ | 已存在,软交换与 WebRTC 音视频交换中心;公网仅经 Nginx 443 暴露,详见第 3 节 |
| FRPS | 0.0.0.0:7000127.0.0.1:12000~12012 | /usr/app/frp/ | 接收 WSL 端反向穿透,仅绑定本地回环 |
| coTURN | 0.0.0.0:3478 (UDP/TCP)31000-31040/UDP | /etc/turnserver.conf | WebRTC NAT 穿透与媒体中继 |
3. WebRTC 音视频与会议背景音
这两块能力都跑在已存在的 FreeSWITCH 上,不需要重装,但依赖的模块与配置分散在 freeswitch/autoload_configs/ 与 freeswitch/dialplan/,改动前先看清链路。
3.1 两条互不通用的 WebRTC 信令链路
| 链路 | FreeSWITCH 端点 | Nginx 公网路径 | 使用方 |
|---|---|---|---|
SIP over WSS(Sofia internal) | :5066 明文 WS、:7443 WSS(sip_profiles/internal.xml) | fs.wangijun.com/ → https://172.21.38.245:7443 | 坐席软电话(callout-webpage 的 use-sip-softphone,地址来自 callout-server agents.sipWsUrl) |
Verto(mod_verto) | :8081 明文、:8082 加密(autoload_configs/verto.conf.xml) | fs.wangijun.com/verto,以及工作台域名下的精确匹配 = /verto → http://172.21.38.245:8081 | callflow-webpage 的 /verto-videophone(use-verto-client) |
两条链路的上游协议恰好相反且不能互换:Sofia 侧必须写 https://…:7443,Verto 侧必须写明文 http://…:8081(TLS 在 Nginx 终结,8082 的自签 wss.pem 不在公网路径上)。逐条规则与排障见 nginx/README.md 第 2.4 节。Verto 只承载信令,媒体仍走 external_rtp_ip 与 30000-30199/UDP,必要时经 coTURN 中继。
mod_av / mod_rtc / mod_verto 由 autoload_configs/modules.conf.xml 加载,缺一个视频页就只能起音频。 号码平面由 dialplan/default.xml 划分:
| 号码段 | 去向 | 说明 |
|---|---|---|
50xx | socket 127.0.0.1:9911 async full | 交给 callflow-esl 按 business_code / 被叫号码选业务;callout-server softphone.serviceNumber(当前 5020)必须落在此段内 |
10xx | Local_Extension → bridge user/<ext>@$${domain} | 分机互拨,同时设置 video_passthru、关键帧请求与 jitterbuffer_msec=60:120:20 等视频参数;分机 1000-1030 定义在 directory/default/ |
30xx | conference $1@default | 会议室直拨 |
9196 | echo | 回音测试,排查单向音频/视频用 |
3.2 会议背景音
链路是四段,任何一段缺失都只表现为“没声音”,不会报错:
autoload_configs/modules.conf.xml加载mod_local_stream;autoload_configs/local_stream.conf.xml声明moh/8000与moh/16000等保持音/背景音流 (对齐通用容器包/data/docker_fs_server/标准定义,字段含义见 FreeSWITCH 模块配置手册 §6.2);- 素材放到宿主机
/usr/local/freeswitch/share/freeswitch/sounds/music/{8000,16000}/(预置办公室底噪素材); 通用容器包docker_fs_server.tar.gz中已直接内置该素材(解压即用);在非容器化的独立宿主机上若需部署, 可直接取用包内素材并按采样率分目录存放; - callflow-esl 的
backgroundAudio.profiles.office.streamUrl(local_stream://moh/16000)必须与第 2 步的name完全一致;实际是否播放由业务调用ctx.conference.startBackgroundAudio()决定,配置里的enabled/volume目前没有消费方。
💡 会议场景流式与整段 WAV 约束说明:当
tts.profiles.stream.playbackPrefix为"shout://"(当前阿里云部署现场配置)时, 会议场景tts.use.conference必须配置为"wav"——因为mod_shout关闭时要 join 自己的 curl reader 线程(按 500ms 粒度让出), 实测阻塞 0.1~2.0 秒,而这次关闭跑在mod_conference唯一的 20ms 混音线程上,背景音与其他成员语音都会听得出中断。 若未来现场将流式前缀切换为"audio_fork://"(原生 PCM16 流),则conference也可安全配置为"stream"。
4. 前端与 ESL 部署/更新操作指南
4.1 步骤一:构建前端产物与 ESL 二进制
在本地(Windows / 开发机)根目录下执行构建:
bash
# 1. 构建两个 Quasar 前端 SPA 静态包 (默认 API 前缀为同域 /api)
bun run --cwd apps/callflow-webpage build
bun run --cwd apps/callout-webpage build
# 2. 构建 callflow-esl Linux x64 独立二进制
bun run --cwd apps/callflow-esl build4.2 步骤二:上传并部署至阿里云服务器
bash
# 1. 创建远程目标目录
ssh aliyun "mkdir -p /usr/app/webpage/{callflow-webpage,callout-webpage}/dist/spa /usr/app/callflow-esl"
# 2. 同步前端静态 SPA 产物(精准部署至 dist/spa 目录)
scp -r apps/callflow-webpage/dist/spa/* aliyun:/usr/app/webpage/callflow-webpage/dist/spa/
scp -r apps/callout-webpage/dist/spa/* aliyun:/usr/app/webpage/callout-webpage/dist/spa/
# 3. 同步 callflow-esl 二进制与配置文件
scp apps/callflow-esl/dist/callflow-esl aliyun:/usr/app/callflow-esl/
scp deploy/aliyun/callflow-esl/callflow-esl.config.toml aliyun:/usr/app/callflow-esl/config.toml4.3 步骤三:权限设置与服务重启
登录阿里云执行服务重载与生效:
bash
ssh aliyun
# 1. 设置可执行权限与目录属主(必须保证 a+rX 权限,避免 Nginx 404)
chmod +x /usr/app/callflow-esl/callflow-esl
chmod -R a+rX /usr/app/webpage/
chown -R aivoice:aivoice /usr/app/callflow-esl /usr/app/webpage
# 2. 重启 callflow-esl 服务
sudo systemctl restart callflow-esl
sudo systemctl status callflow-esl
# 3. 检查 Nginx 配置并平滑重载
sudo nginx -t && sudo systemctl reload nginx5. 验证与排障
bash
# 1. 验证 callflow-esl 监听状态 (9911 与 9912)
ss -tulpn | grep -E '9911|9912'
# 2. 验证 ESL HTTP 接口健康状态
curl -H "Token: esl-0x21" http://127.0.0.1:9912/health
# 3. 验证 FreeSWITCH Inbound ESL 状态 (已有 12015 端口)
nc -zv 127.0.0.1 12015
# 4. 验证公网 HTTPS / WSS 域名解析与证书状态
curl -Iv https://callflow.wangijun.com/
curl -Iv https://callout.wangijun.com/
curl -Iv https://ai-voice.wangijun.com/
# 5. 验证两条 WebRTC 信令端点在监听 (Sofia WS/WSS 与 Verto 明文口)
ss -tulpn | grep -E '5066|7443|8081'
# 6. 验证会议背景音模块与素材
fs_cli -x "module_exists mod_local_stream" # 期望 true
fs_cli -x "local_stream show" # 期望列出 moh/8000 与 moh/16000 等流
ls /usr/local/freeswitch/share/freeswitch/sounds/music/16000/