docs(collabora): organize deployment guides and fix proxy chain

This commit is contained in:
wren
2026-05-11 17:54:39 +08:00
parent dcc0f3c30d
commit f788149ca7
16 changed files with 2959 additions and 15 deletions
@@ -0,0 +1,800 @@
# Collabora 正确配置全流程
## 1. 文档目标
本文档用于沉淀 LeAudit 当前 Collabora 集成的**正确配置全流程**,便于:
- 本机继续维护
- 迁移到新服务器
- 上线前后按清单验收
- 遇到故障时快速排查
本文档同时包含两类信息:
- 当前环境已经验证可用的实际配置
- 可迁移到其他服务器的模板化配置说明
当前已验证可用的主链路为:
```text
http://172.16.0.59:5173
```
注意:
**浏览器入口、前端生成的 WOPI 地址、Collabora iframe 地址、nginx 转发头、Collabora 白名单、CSP 的 host 必须完全一致。**
如果后续要改成域名方案,必须整套一起切换,不要域名/IP 混用。
---
## 2. 参数模板
迁移到新服务器时,建议先把下面这些参数定义清楚,再开始修改配置:
```text
<PROJECT_ROOT> LeAudit 项目根目录
<COLLABORA_DEPLOY_ROOT> Collabora 部署目录
<APP_HOST> 浏览器实际访问的主机名或 IP
<APP_PORT> 前端代理入口端口,默认 5173
<FRONTEND_DEV_PORT> Next 开发服务端口,默认 5193
<BACKEND_PORT> 后端服务端口,默认 8096
<COLLABORA_PORT> Collabora 容器端口,默认 9980
<DOCUMENT_BASE_URL> 文档读写后端基础地址
```
当前环境对应值:
```text
<PROJECT_ROOT> = /home/wren-dev/Porject/leaudit-platform
<COLLABORA_DEPLOY_ROOT> = /home/wren-dev/Porject/collabora-backup
<APP_HOST> = 172.16.0.59
<APP_PORT> = 5173
<FRONTEND_DEV_PORT> = 5193
<BACKEND_PORT> = 8096
<COLLABORA_PORT> = 9980
<DOCUMENT_BASE_URL> = http://172.16.0.59:8096/docauditai/
```
---
## 3. 当前架构
当前链路如下:
1. 浏览器访问前端入口:`http://172.16.0.59:5173`
2. `5173` 上运行 nginx 代理
3. nginx 将普通前端请求转发到 Next:`127.0.0.1:5193`
4. nginx 将 Collabora 请求转发到容器:`127.0.0.1:9980`
5. 前端通过 `/api/collabora/config` 生成:
- `iframeUrl`
- `WOPISrc`
6. Collabora 再通过 `/wopi/files/...` 回调前端获取文件信息与文件内容
简化后的链路:
```text
Browser
-> 172.16.0.59:5173
-> nginx proxy
-> 127.0.0.1:5193 (Next 前端)
-> 127.0.0.1:9980 (Collabora)
```
---
## 4. 关键目录与文件
### 4.1 项目目录
```text
<PROJECT_ROOT>
```
当前实际值:
```text
/home/wren-dev/Porject/leaudit-platform
```
### 4.2 Collabora 部署目录
```text
<COLLABORA_DEPLOY_ROOT>
```
当前实际值:
```text
/home/wren-dev/Porject/collabora-backup
```
### 4.3 本次关键文件
- 前端环境变量
- `legal-platform-frontend/.env`
- Collabora iframe 配置生成
- `legal-platform-frontend/lib/services/collabora.config.server.ts`
- nginx 代理配置
- `deploy/collabora-proxy/conf.d/collabora.conf`
- Collabora compose 配置
- `/home/wren-dev/Porject/collabora-backup/docker-compose.yml`
- Collabora 主配置
- `/home/wren-dev/Porject/collabora-backup/coolwsd-config/coolwsd.xml`
---
## 5. 前置要求
开始前请确认:
- Docker 可用
- Docker Compose 可用
- 前端、后端可正常启动
- 目标服务器开放需要的端口
- Collabora 镜像已准备好
如需重新导入镜像:
```bash
docker load -i <COLLABORA_DEPLOY_ROOT>/collabora-image-v5.tar
```
当前环境示例:
```bash
docker load -i /home/wren-dev/Porject/collabora-backup/collabora-image-v5.tar
```
需要重点确认的端口:
- `<APP_PORT>`
- `<BACKEND_PORT>`
- `<COLLABORA_PORT>`
---
## 6. 前端正确配置
文件:`legal-platform-frontend/.env`
### 6.1 当前已验证可用配置
```env
API_BACKEND_TARGET=http://172.16.0.59:8096
APP_URL=http://172.16.0.59:5173
DOCUMENT_URL=http://172.16.0.59:8096/docauditai/
COLLABORA_URL=http://172.16.0.59:5173
```
### 6.2 模板写法
迁移到新服务器时,替换为:
```env
API_BACKEND_TARGET=http://<APP_HOST>:<BACKEND_PORT>
APP_URL=http://<APP_HOST>:<APP_PORT>
DOCUMENT_URL=http://<APP_HOST>:<BACKEND_PORT>/docauditai/
COLLABORA_URL=http://<APP_HOST>:<APP_PORT>
```
### 6.3 每个变量的作用
- `APP_URL`
- 决定 `WOPISrc`
- 必须与浏览器实际访问入口一致
- `COLLABORA_URL`
- 决定 iframe 中 `cool.html` 的主机与端口
- `API_BACKEND_TARGET`
- 前端调用后端 API 的入口
- `DOCUMENT_URL`
- WOPI 获取文件、写回文件时使用的后端文档基础地址
### 6.4 为什么必须统一
如果浏览器入口是:
- `http://172.16.0.59:5173`
但前端却生成:
- `http://nas.7bm.co:5173/wopi/files/...`
- `http://nas.7bm.co:5173/browser/dist/cool.html`
就会出现:
- 父页面是 IP
- iframe 是域名
- WOPI 又是另一个 host
- 浏览器按跨源处理
- 最终触发 iframe 拒绝加载、CSP 冲突、`chrome-error://chromewebdata/`
所以前端配置必须与最终入口完全一致。
---
## 7. Collabora iframe 参数生成
文件:`legal-platform-frontend/lib/services/collabora.config.server.ts`
### 7.1 当前逻辑
- `WOPISrc = ${APP_URL}/wopi/files/${encodeURIComponent(fileId)}`
- `cool.html = ${COLLABORA_URL}/browser/dist/cool.html?...`
### 7.2 当前建议保留的 UI 默认项
```ts
const uiDefaults = [
"UIMode=compact",
"TextRuler=false",
"TextStatusbar=false",
"TextSidebar=false",
].join(";")
```
### 7.3 已移除的项
- `SavedUIState=false`
原因:
- Collabora 会输出:
- `unknown UI default's component SavedUIState`
- 该项不是必须项,移除后可减少无关噪音日志
---
## 8. nginx 代理正确配置
文件:`deploy/collabora-proxy/conf.d/collabora.conf`
### 8.1 必须代理的路径
以下路径必须明确代理:
- `/wopi/`
- `/browser/`
- `/cool/`
- `/coolws/`
- `/hosting/`
- `/loleaflet/`
- `/`
### 8.2 路径作用
- `/wopi/`
- 前端本地 WOPI 接口
- `/browser/`
- Collabora 页面与静态资源
- `/cool/`
- 文档会话相关路径
- `/coolws/`
- websocket 子通道
- `/hosting/`
- discovery 接口
- `/loleaflet/`
- Collabora 相关资源
- `/`
- 普通前端页面与 API
### 8.3 Collabora 相关转发头
对 Collabora 相关 location,必须统一:
```nginx
proxy_set_header Host <APP_HOST>:<APP_PORT>;
proxy_set_header X-Forwarded-Host <APP_HOST>:<APP_PORT>;
proxy_set_header X-Forwarded-Proto $scheme;
```
当前环境实际值:
```nginx
proxy_set_header Host 172.16.0.59:5173;
proxy_set_header X-Forwarded-Host 172.16.0.59:5173;
proxy_set_header X-Forwarded-Proto $scheme;
```
### 8.4 前端主路由需要补的头
```nginx
proxy_set_header X-Forwarded-Port $server_port;
```
### 8.5 为什么 `/coolws/` 不能漏
如果遗漏 `/coolws/`,就会出现:
- `WOPI` 文件接口已经返回 `200`
- `cool.html` 也能打开
- 但 websocket 子通道建立失败
- 文档仍无法进入编辑状态
本次修复中,`/coolws/` 是一个关键缺失点。
### 8.6 错误跳转修复
针对 Next 开发环境错误返回的绝对地址,需要增加:
```nginx
proxy_redirect http://127.0.0.1:<FRONTEND_DEV_PORT>/ http://<APP_HOST>:<APP_PORT>/;
proxy_redirect http://localhost:<FRONTEND_DEV_PORT>/ http://<APP_HOST>:<APP_PORT>/;
```
当前环境实际值:
```nginx
proxy_redirect http://127.0.0.1:5193/ http://172.16.0.59:5173/;
proxy_redirect http://localhost:5193/ http://172.16.0.59:5173/;
```
否则可能出现:
- 浏览器跳到 `localhost:5193/login?...`
- 远端用户直接无法访问
### 8.7 迁移到新服务器时要替换的项
- `listen 5173;`
- `proxy_pass http://127.0.0.1:5193`
- `proxy_pass http://127.0.0.1:9980`
- 所有 `Host <APP_HOST>:<APP_PORT>`
- 所有 `X-Forwarded-Host <APP_HOST>:<APP_PORT>`
- 所有 `proxy_redirect`
---
## 9. Collabora Docker Compose 正确配置
文件:`<COLLABORA_DEPLOY_ROOT>/docker-compose.yml`
### 9.1 当前关键配置
```yaml
services:
collabora:
image: docker-collabora:v5
container_name: collabora_code
privileged: true
ports:
- "9980:9980"
environment:
- "domain=.*"
- "extra_params=--o:ssl.enable=false --o:ssl.termination=false --o:logging.level=warning --o:security.seccomp=false"
```
### 9.2 不要再保留旧参数
不要再使用:
```text
--o:net.frame_ancestors=http://*
```
原因:
- 这是过时配置
- 会污染最终 `Content-Security-Policy`
- 会让 `frame-ancestors` 混乱
- 浏览器会直接拦 iframe
### 9.3 当前正确做法
- 删除 `net.frame_ancestors`
-`coolwsd.xml` 中显式设置 `content_security_policy`
### 9.4 新服务器迁移要点
迁移时需要确认:
- 镜像已导入
- `docker-compose.yml` 中挂载目录存在
- 插件目录存在:
- `mycustom_collabora_plugins`
- 脚本目录存在:
- `custom_python_scripts`
- `<COLLABORA_PORT>` 未被占用
---
## 10. Collabora 主配置正确写法
文件:`<COLLABORA_DEPLOY_ROOT>/coolwsd-config/coolwsd.xml`
### 10.1 WOPI 白名单
模板写法:
```xml
<alias_groups mode="groups">
<group>
<host desc="Frontend Host" allow="true">http://<APP_HOST_REGEX>:<APP_PORT></host>
</group>
</alias_groups>
```
当前环境实际值:
```xml
<alias_groups mode="groups">
<group>
<host desc="LAN Frontend" allow="true">http://172\.16\.0\.59:5173</host>
</group>
</alias_groups>
```
### 10.2 CSP 配置
模板写法:
```xml
<content_security_policy>frame-ancestors http://<APP_HOST>:<APP_PORT>;</content_security_policy>
```
当前环境实际值:
```xml
<content_security_policy>frame-ancestors http://172.16.0.59:5173;</content_security_policy>
```
### 10.3 不推荐写法
不要再使用复杂 alias 正则,例如:
```xml
http://172\.16\.0\.[0-9]{1,3}(:[0-9]{1,5})?
```
这在当前环境中已经实测触发过:
- `Invalid regular expression for allowed host`
- `Bad URI syntax`
因此当前方案统一改为显式 host。
---
## 11. 正确重启顺序
### 11.1 前后端
```bash
cd <PROJECT_ROOT>
./leaudit.sh restart
```
### 11.2 代理
```bash
docker restart leaudit-collabora-proxy
```
### 11.3 Collabora
推荐直接强制重建,而不是简单 restart:
```bash
cd <COLLABORA_DEPLOY_ROOT>
docker-compose up -d --force-recreate collabora
```
### 11.4 为什么要 force-recreate
如果只执行:
```bash
docker restart collabora_code
```
旧容器里的环境变量可能仍保留,尤其是:
- `extra_params`
本次就遇到过:
- compose 文件已经删掉了 `net.frame_ancestors`
- 但旧容器环境里仍残留该参数
- 只有 `--force-recreate` 之后才真正清理干净
### 11.5 推荐标准重建流程
```bash
cd <PROJECT_ROOT>
./leaudit.sh restart
docker restart leaudit-collabora-proxy
cd <COLLABORA_DEPLOY_ROOT>
docker-compose up -d --force-recreate collabora
```
---
## 12. 正确验证步骤
### 12.1 验证前端入口
```bash
curl -I http://<APP_HOST>:<APP_PORT>/
```
期望:
- 返回 `307`
- 跳转到 `http://<APP_HOST>:<APP_PORT>/login?...`
当前环境示例:
```bash
curl -I http://172.16.0.59:5173/
```
### 12.2 验证 discovery
```bash
curl -I http://<APP_HOST>:<APP_PORT>/hosting/discovery
```
期望:
- `200 OK`
### 12.3 验证 Collabora 页面
```bash
curl -I http://<APP_HOST>:<APP_PORT>/browser/dist/cool.html
```
期望:
- `200 OK`
- 响应头包含 `Content-Security-Policy`
- `frame-ancestors` 围绕当前 `<APP_HOST>:<APP_PORT>` 收口
### 12.4 验证 WOPI 文件接口
通过页面实际访问时,日志里应看到:
```text
GET /wopi/files/... 200
```
### 12.5 验证 websocket 子通道
Collabora 日志中应能看到类似:
- `/coolws/forkit`
- `/coolws/newchild`
- `Upgrading to WebSocket`
这说明文档会话已建立。
### 12.6 上线验收清单
上线到新服务器后,至少完成以下验收:
- 能打开登录页
- 能成功登录
- 能打开 2~3 个不同文档
- 能进入编辑态
- 能保存并再次打开
- 浏览器控制台不再出现:
- `refused to connect`
- `chrome-error://chromewebdata/`
- `Framing ... violates Content Security Policy`
- Collabora 日志不再出现:
- `Invalid regular expression for allowed host`
- `Bad URI syntax`
- `No authorized hosts found`
---
## 13. 浏览器侧正确测试方式
如果浏览器之前已经打开过:
- `nas.7bm.co`
- 或旧的失败 iframe 页面
即使后端已经修好,也可能继续残留:
- `chrome-error://chromewebdata/`
- 错误 iframe 上下文
- 跨源错误
### 正确做法
1. 关闭旧标签页
2. 打开无痕窗口
3. 只访问:
- `http://<APP_HOST>:<APP_PORT>/login`
4. 登录后直接进入文档页面
5. 不要从旧域名页面跳转到新 IP 页面
当前环境示例:
- `http://172.16.0.59:5173/login`
---
## 14. 本次实际修复过的问题
### 问题 1:错误跳转到 `localhost:5193`
原因:
- 代理头不完整
- Next 在开发环境生成了错误绝对地址
修复:
- 增加 `X-Forwarded-Host` / `X-Forwarded-Port`
- 增加 `proxy_redirect`
### 问题 2`/coolws/` 未代理
原因:
- 只代理了 `/cool/`,漏了 websocket 子通道
修复:
- 增加 `/coolws/` 到 Collabora 容器的代理
### 问题 3Collabora 白名单正则错误
原因:
- 复杂 alias 正则不兼容当前 coolwsd 解析
修复:
- 改为显式 host
### 问题 4CSP / frame-ancestors 冲突
原因:
- 旧的 `net.frame_ancestors=http://*`
- 域名与 IP 混用
修复:
- 删除旧参数
- 使用 `content_security_policy` 显式配置
- 强制重建容器
### 问题 5`SavedUIState` 无关告警
原因:
- `ui_defaults` 里传了 Collabora 当前不识别的项
修复:
-`legal-platform-frontend/lib/services/collabora.config.server.ts` 中移除该项
---
## 15. 回切域名方案时的注意事项
如果后续要恢复域名方案,不能只改其中一项,必须一起改:
- 前端 `.env`
- nginx 代理头与 `proxy_redirect`
- Collabora 白名单
- Collabora CSP `frame-ancestors`
### 15.1 推荐原则
上线时只选一种主链路:
- 全域名
- 全 IP
不要混合:
- 父页面域名
- iframe IP
- WOPI 又是另一个 host
否则最终还是会回到浏览器跨源与 iframe 拦截问题。
---
## 16. 推荐日常运维命令
### 查看前后端状态
```bash
cd <PROJECT_ROOT>
./leaudit.sh doctor
```
### 重启前后端
```bash
./leaudit.sh restart
```
### 重建 Collabora
```bash
cd <COLLABORA_DEPLOY_ROOT>
docker-compose up -d --force-recreate collabora
```
### 查看 Collabora 日志
```bash
docker logs --tail 200 collabora_code
```
### 查看代理日志
```bash
tail -n 200 <PROJECT_ROOT>/deploy/collabora-proxy/logs/error.log
```
---
## 17. 新服务器迁移 Checklist
### 17.1 准备阶段
- [ ] 准备好项目代码目录 `<PROJECT_ROOT>`
- [ ] 准备好 Collabora 部署目录 `<COLLABORA_DEPLOY_ROOT>`
- [ ] 准备好 Collabora 镜像 tar 或镜像仓库访问方式
- [ ] 确认 `<APP_HOST>`
- [ ] 确认 `<APP_PORT>``<BACKEND_PORT>``<COLLABORA_PORT>` 不冲突
### 17.2 配置阶段
- [ ] 修改 `legal-platform-frontend/.env`
- [ ] 修改 `deploy/collabora-proxy/conf.d/collabora.conf`
- [ ] 修改 `docker-compose.yml`
- [ ] 修改 `coolwsd.xml`
### 17.3 启动阶段
- [ ] 导入 Collabora 镜像
- [ ] 启动前后端
- [ ] 重启代理
- [ ] 强制重建 Collabora 容器
### 17.4 验证阶段
- [ ] `curl -I http://<APP_HOST>:<APP_PORT>/`
- [ ] `curl -I http://<APP_HOST>:<APP_PORT>/hosting/discovery`
- [ ] `curl -I http://<APP_HOST>:<APP_PORT>/browser/dist/cool.html`
- [ ] 浏览器无痕访问登录页
- [ ] 打开并保存至少一个文档
### 17.5 故障定位阶段
若失败,优先检查:
- [ ] 前端 `.env` 与实际入口是否一致
- [ ] nginx 是否代理了 `/coolws/`
- [ ] `proxy_redirect` 是否仍指向旧地址
- [ ] `coolwsd.xml` 白名单是否与实际 host 一致
- [ ] compose 是否仍残留旧 `extra_params`
- [ ] Collabora 是否已 `force-recreate`
---
## 18. 当前结论
当前这套正确配置的核心原则只有一句话:
**浏览器入口、前端生成的 WOPI 地址、Collabora iframe 地址、代理转发头、Collabora 白名单、CSP 来源,必须全部使用同一个 host。**
本次已经验证可用的 host 为:
```text
172.16.0.59:5173
```
如果迁移到新服务器,请先替换 `<APP_HOST>` 等参数,再按本文档的重启与验证步骤执行。