OnlyOffice 演示环境部署与验证指南(130 + ruoyioffice.com)
生成日期:2026-06-21
适用环境:演示虚拟机 192.168.30.130(已装 Docker),经内网穿透公网 182.92.106.252 / ruoyioffice.com
关联配置:ruoyi-office.conf、docker-compose.onlyoffice.yml、application-prod.yaml
0. 环境事实与结论
| 项 | 值 |
|---|---|
| 部署主机 | 192.168.30.130(Docker:MySQL/Redis/yudao-server/nginx 均为容器) |
| 公网映射 | 182.92.106.252 → 域名 ruoyioffice.com(内网穿透) |
| 前端 | http://ruoyioffice.com/web(nginx 80) |
| 后端 | http://ruoyioffice.com:48080(直连,穿透 48080) |
| OnlyOffice | Docker 容器,130 宿主机端口 8081;阿里云 ECS 将公网 18081 转发到 130:8081 |
三处关键地址(务必区分视角): ✅ 当前采用「公网 18081 直连」方案
| 配置项 | 值 | 视角 / 原因 |
|---|---|---|
yudao.onlyoffice.server-url | http://ruoyioffice.com:18081 | 浏览器加载 api.js;浏览器直连公网 18081(→ 转发到 130:8081) |
yudao.onlyoffice.callback-base-url | http://192.168.30.130:48080 | OnlyOffice 容器回访后端;容器与后端同在 130,走内网 IP,不出公网 |
yudao.onlyoffice.jwt-secret | ruoyi-office-onlyoffice-secret | 必须与容器实际 JWT_SECRET 完全一致(见 6.1 自检) |
端口链路:浏览器 →
ruoyioffice.com:18081(阿里云 ECS)→ 转发/穿透 →130:8081(OnlyOffice 容器8081:80)。
回调链路:OnlyOffice 容器(130)→192.168.30.130:48080(后端,同主机内网直达)。
⚠️ 混合内容:前端与 OnlyOffice 当前同为 HTTP,可正常加载;若将来前端升 HTTPS,则 18081 直连(HTTP)会被浏览器拦截,届时须改走 nginx 反代 + HTTPS(见附录方案 B)。
1. 数据流
最终用户浏览器
│ ① GET http://ruoyioffice.com:48080/admin-api/contract/onlyoffice/config → yudao 后端(130:48080)
│ ② GET http://ruoyioffice.com:18081/web-apps/.../api.js → 阿里云 ECS:18081 → 转发 → OnlyOffice(130:8081)
▼
OnlyOffice 容器(130)
│ ③ GET http://192.168.30.130:48080/admin-api/contract/onlyoffice/download?token= (拉原文)
└ ④ POST http://192.168.30.130:48080/admin-api/contract/onlyoffice/callback?token= (回存)2. 部署前检查
- [ ] 130 上
docker ps正常,后端容器yudao-server监听0.0.0.0:48080 - [ ] nginx 容器正常,当前使用
ruoyi-office.conf - [ ] 后端 Spring profile =
prod(加载application-prod.yaml) - [ ] 已执行合同模块 SQL(含
20260621_update缩略图/预览字段) - [ ] 130 可访问外网(拉镜像、OSS 预签名文件)
- [ ] 130 内存建议 ≥ 4GB(OnlyOffice 首次启动较吃内存)
3. 在 130 上部署 OnlyOffice(Docker)
以下命令均在 192.168.30.130 上执行。
130 上通常没有完整ruoyi-office源码目录,只需单独建目录并拷贝 compose 文件即可。
3.0 创建目录并拷贝 compose 文件
在 130 上创建目录:
mkdir -p /data/onlyoffice在你本机(Windows)把 compose 文件拷到 130:
# 源文件(本机仓库路径,按实际调整)
# w:\ruoyi-office\ruoyi-office\script\docker\docker-compose.onlyoffice.yml
scp w:\ruoyi-office\ruoyi-office\script\docker\docker-compose.onlyoffice.yml root@192.168.30.130:/data/onlyoffice/也可用 WinSCP / Xftp 等工具,把 docker-compose.onlyoffice.yml 上传到 130 的 /data/onlyoffice/。
上传后确认:
ls -l /data/onlyoffice/docker-compose.onlyoffice.yml3.1 拉取镜像并启动
OnlyOffice 镜像约 2GB+,首次拉取较慢。若报
registry-1.docker.io ... Timeout,见下方 3.1.1。
建议先配置 Docker 镜像加速(130 上执行一次即可):
mkdir -p /etc/docker
cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.1ms.run",
"https://docker.mirrors.ustc.edu.cn"
]
}
EOF
systemctl daemon-reload
systemctl restart docker
# 确认加速器已生效
docker info | grep -A 5 "Registry Mirrors"然后拉取并启动:
cd /data/onlyoffice
# 先单独拉镜像(便于观察进度;成功后再 up)
docker pull onlyoffice/documentserver:8.2
docker compose -f docker-compose.onlyoffice.yml up -d
# 跟踪启动日志,出现就绪信息后 Ctrl+C
docker logs -f onlyoffice-documentserver3.1.1 镜像拉取失败(Timeout / connection reset)
报错示例:
Get "https://registry-1.docker.io/v2/": ... Client.Timeout exceeded while awaiting headers方案 A:换国内镜像源手动拉取 + 打标签(推荐,与 MySQL 部署方式一致)
# 华为云同步的 docker.io 镜像(与 compose 里 image 名一致即可 up)
docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/onlyoffice/documentserver:8.2
docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/onlyoffice/documentserver:8.2 \
onlyoffice/documentserver:8.2
docker images | grep onlyoffice
cd /data/onlyoffice
docker compose -f docker-compose.onlyoffice.yml up -d方案 B:阿里云个人加速器(最稳,需登录阿里云控制台)
- 打开 容器镜像服务 → 镜像加速器
- 复制你的专属地址,例如
https://xxxxxx.mirror.aliyuncs.com - 写入
/etc/docker/daemon.json的registry-mirrors第一项,重启 Docker 后再docker pull onlyoffice/documentserver:8.2
方案 C:本机拉取后离线导入 130(130 完全不能访问外网时)
在你 Windows 本机(Docker Desktop 已启动):
docker pull onlyoffice/documentserver:8.2
docker save onlyoffice/documentserver:8.2 -o onlyoffice-8.2.tar
scp onlyoffice-8.2.tar root@192.168.30.130:/data/onlyoffice/在 130 上:
cd /data/onlyoffice
docker load -i onlyoffice-8.2.tar
docker compose -f docker-compose.onlyoffice.yml up -d
version: '3'的 obsolete 警告可忽略,不影响运行。
docker-compose.onlyoffice.yml 关键点:
services:
onlyoffice-documentserver:
image: onlyoffice/documentserver:8.2
ports:
- '8081:80' # 宿主机 8081 → 容器 80
environment:
- JWT_ENABLED=true
- JWT_SECRET=ruoyi-office-onlyoffice-secret # 必须与后端 jwt-secret 一致
- JWT_HEADER=Authorization3.2 验证容器本身(宿主机直连)
curl -I http://127.0.0.1:8081/ # 期望 200 / 302
curl -I http://192.168.30.130:8081/ # nginx 容器即用此地址访问
docker ps | grep onlyoffice # STATUS = Up4. 配置后端(application-prod.yaml)
确认 yudao 段已包含(本次已写入仓库):
yudao:
onlyoffice:
enabled: true
server-url: http://ruoyioffice.com:18081 # 浏览器直连公网 18081
jwt-secret: ruoyi-office-onlyoffice-secret
callback-base-url: http://192.168.30.130:48080修改后重启后端容器使配置生效。
5. 开放公网 18081 端口(阿里云 ECS)
OnlyOffice 经阿里云 ECS 把公网 18081 转发到 130:8081。要让公网可达,两道关:
- 阿里云安全组(控制台,最关键):入方向放行
18081/tcp,授权对象0.0.0.0/0(正式建议限公司出口 IP)。 - 服务器防火墙(public zone,不要放 docker zone):
sudo firewall-cmd --zone=public --add-port=18081/tcp --permanent
sudo firewall-cmd --reload
firewall-cmd --zone=public --list-ports验证:浏览器打开 http://ruoyioffice.com:18081/ 看到 ONLYOFFICE 欢迎页即通。
本方案不使用 nginx
/onlyoffice子路径反代;该反代作为备选保留在附录,仅在前端升级 HTTPS 时启用。
6. JWT 与回调连通性自检(最易踩坑,必做)
6.1 JWT secret 自检 ⚠️
OnlyOffice 8.x 默认开启 JWT;若容器不是用本仓库 compose(带 JWT_SECRET)启动,会自动生成随机 secret,导致后端签的 token 容器不认 → 「文档打不开 / token 无效」。
# 查看容器实际生效的 secret,应输出 ruoyi-office-onlyoffice-secret
docker exec onlyoffice-documentserver /var/www/onlyoffice/documentserver/npm/json \
-f /etc/onlyoffice/documentserver/local.json 'services.CoAuthoring.secret.session.string'
# 顺带核对 inbox/outbox(部分版本分开存)
docker exec onlyoffice-documentserver /var/www/onlyoffice/documentserver/npm/json \
-f /etc/onlyoffice/documentserver/local.json 'services.CoAuthoring.secret.inbox.string'若输出不是 ruoyi-office-onlyoffice-secret:说明容器不是用本 compose 起的。用本仓库 compose 重建:
cd /data/onlyoffice
docker compose -f docker-compose.onlyoffice.yml down
docker compose -f docker-compose.onlyoffice.yml up -d6.2 回调连通性自检
OnlyOffice“打不开/不保存”≈ 容器访问不到后端。在 130 执行:
docker exec -it onlyoffice-documentserver bash
# 容器 → 后端(与 callback-base-url 一致)
curl -I "http://192.168.30.130:48080/admin-api/contract/onlyoffice/enabled"
# 期望 HTTP/1.1 200(或 401/无 body 也说明网络可达,重点是不能 Connection refused / timeout)
exit若不可达:
- 后端是否监听
0.0.0.0:48080(容器内0.0.0.0才能被其他容器经宿主机 IP 访问) - 130 防火墙/安全组是否放行 48080 内网
- 备选:给 compose 加
extra_hosts: ['host.docker.internal:host-gateway'],并把 callback 改为http://host.docker.internal:48080
callback-base-url 不要带
/admin-api后缀、不要带末尾/,后端代码会自动拼/admin-api/contract/onlyoffice/...。
7. 业务功能验证清单
登录管理端:http://ruoyioffice.com/web(打开浏览器 DevTools → Network)
| # | 操作 | 期望 |
|---|---|---|
| 1 | 合同 → 合同模板 → 配置(含 docx 的模板) | onlyoffice/enabled 返回 true |
| 2 | 观察编辑器区域 | 加载 OnlyOffice iframe(非 HTML 富文本) |
| 3 | Network 查看 | 成功加载 http://ruoyioffice.com:18081/web-apps/.../api.js(200) |
| 4 | 修改正文,等待自动保存(约 10~30s) | 无报错;刷新后内容仍在 |
| 5 | 后端日志搜索 [onlyoffice callback] | 有 status=2/6 成功记录 |
| 6 | 合同模板列表 | 卡片网格 + 缩略图/POI 文本封面 |
| 7 | 合同起草 → 选择模板(弹窗) | 选模板生成正文,占位符已填充 |
| 8 | 提交审批并通过 → 合同台账 | 「合同文件」中有生成的 Word/PDF |
| 9 | 台账点击预览 | 弹窗预览(非浏览器直接下载);私有 OSS 走预签名不报 AccessDenied |
8. 常见问题
| 现象 | 排查 |
|---|---|
| 编辑器一直转圈 | docker ps 确认 OnlyOffice Up;浏览器能否打开 http://ruoyioffice.com:18081/ 欢迎页 |
| api.js 加载失败 | 阿里云安全组 + firewalld 是否放行 18081;ruoyioffice.com:18081→130:8081 转发是否生效 |
| Token 无效 / 文档打不开 | 6.1 JWT 自检:容器实际 secret 是否 = 后端 jwt-secret;后端是否重启 |
| 能打开但不保存 | 6.2 回调自检;后端日志 [onlyoffice callback];callback-base-url 是否为 192.168.30.130:48080 |
| HTTPS 站点编辑器被拦 | 混合内容:前端升 HTTPS 后须改走 nginx 反代 + HTTPS(附录方案 B),不能再用 18081 明文直连 |
| 保存后端 Tika/OOM | 已修复:回调显式 MIME + pin commons-compress;确认部署最新 contract 模块 |
9. 磁盘占用风险与防范(重要)
OnlyOffice 容器有两类「吃磁盘」来源,本地 Windows 比生产 Linux 更严重,务必区分:
9.1 根因
| 来源 | 说明 | 影响范围 |
|---|---|---|
| core dump(崩溃转储) | OnlyOffice 转换/文档进程崩溃时生成 core 文件,单个可达 GB 级,进程反复崩则反复生成 | 本地 + 生产都需防 |
| 容器日志膨胀 | stdout/stderr 被 Docker 以 json-file 无限累积 | 本地 + 生产都需防 |
WSL2 ext4.vhdx 只增不减 | Windows Docker Desktop 把所有数据放进 C 盘虚拟磁盘,容器删了数据该文件也不缩小 | 仅本地 Windows |
「删了 tmp 又出现」= 容器仍在运行、崩溃进程持续 dump;删结果不掐源头无效。
本地 C 盘满主要叠加了 WSL2 vhdx 不回收的问题,生产 Linux 没有此问题,风险远低于本地表现。
9.2 生产防范(compose 已内置)
docker-compose.onlyoffice.yml 已加入:
ulimits:
core: 0 # 禁止生成 core dump(根治反复的大 dump 文件)
logging:
driver: 'json-file'
options:
max-size: '10m' # 单日志文件上限
max-file: '3' # 最多保留 3 个,超出滚动删除部署后核对:
docker inspect onlyoffice-documentserver --format '{{ .HostConfig.Ulimits }}'
docker inspect onlyoffice-documentserver --format '{{ .HostConfig.LogConfig }}'9.3 生产巡检 / 兜底
# 看容器可写层与卷占用
docker ps -s | grep onlyoffice
docker system df -v | grep onlyoffice
# 全局禁用 core dump(Linux 宿主,叠加保险)
echo '* hard core 0' >> /etc/security/limits.conf
sysctl -w kernel.core_pattern=/dev/null
# 定期清理(OnlyOffice 转换缓存)
docker exec onlyoffice-documentserver bash -c 'rm -rf /var/lib/onlyoffice/documentserver/App_Data/cache/files/* 2>/dev/null'
# 建议:把 /data 单独挂大盘;监控磁盘水位告警9.4 本地 Windows 止血
# 1. 停容器(先掐 dump 源头)
docker stop onlyoffice-documentserver
# 2. 新建 C:\Users\<你>\.wslconfig:
# [wsl2]
# coreDump=false
# memory=6GB
# 3. 重启 WSL 生效
wsl --shutdown
# 4. 压缩已占用但空闲的 vhdx(diskpart: select vdisk → attach readonly → compact → detach)10. 回滚
# 关闭高保真(后端降级为 HTML 富文本):application-prod.yaml → enabled: false,重启后端
# 停止文档服务:
docker compose -f docker-compose.onlyoffice.yml down
# nginx 回滚:恢复 backup 的旧 ruoyi-office.conf 并 reload