☰
OnlyOffice配置HTTPS:Nginx反向代理与WebSocket代理实战
2026/10/1 5:43:09 网站建设 项目流程

最近有同事在生产环境倒腾 OnlyOffice,问我最多的一个问题就是:明明服务已经跑起来了,浏览器地址栏也正常打开,为什么集成到系统里一编辑文档就报错、或者保存时提示“无法连接到文档服务器”。排查到最后,几乎都是同一个原因——OnlyOffice 还停留在 HTTP 明文访问,而业务系统已经是 HTTPS 了。浏览器把“HTTPS 页面里发起 HTTP 请求”的行为直接视为混合内容,咔嚓一下给你拦掉。这篇就专门写 OnlyOffice 配置 HTTPS 访问这件事,从方案选型到 Nginx 反向代理,再到常见坑位的排查,一次性说清楚。

我自己经历过从裸 IP 访问到正规域名 HTTPS 的整个改造过程,也会把踩过的问题一并列出来,给正在做同样事情的运维、开发同学当一份参考。这篇文章适合的对象很明确:要么你已经部署好了 OnlyOffice Document Server 正在为编辑页打不开发愁,要么你准备在自建网盘、OA、项目管理软件里集成 OnlyOffice,趁早把 HTTPS 链路设计对,省得后面返工。

1. 整体设计与方案选型

1.1 为什么 HTTPS 会是刚需而不仅仅是“更好”

先说一个很多新手容易忽略的点:OnlyOffice 本身是一个浏览器端在线编辑套件,前端通过 JavaScript SDK 加载文档编辑器,编辑器内部再去访问文档转换、协同编辑的接口。也就是说,页面里会有大量的 XHR 和 WebSocket 请求动态发生。如果你把业务系统跑在 HTTPS 下,而文档服务地址还是 http:// 开头,现代浏览器会严格拦截这类跨协议请求。常见的表现包括:

  • 编辑器加载到一半白屏,控制台报Mixed Content错误;
  • 文档能打开,但“保存”按钮一直转圈;
  • 协同编辑时连接状态异常,多人同时编辑时看不到对方的光标。

解决办法只有一个方向:让 OnlyOffice 的访问地址和上层业务系统保持同样的协议,也就是说给它也配上 HTTPS。

这里要提一个容易被带偏的思路。有人可能在容器层面直接把 OnlyOffice 容器内部 Nginx 改造成监听 443,或者把证书挂载进容器。这个方案不能说完全不行,但维护成本高,升级镜像后配置容易丢,而且 TLS 证书续期、多站点扩展都麻烦。我更推荐在宿主机上用一个独立的 Nginx 做反向代理,统一终结 TLS,再把请求转给 OnlyOffice 容器的 80 端口。这样职责清晰,证书管理也集中在一个入口。

1.2 两种主流架构对比:直挂证书 vs 反向代理

我自己实际做过两种测试,结论非常明确:反向代理是更适合绝大部分团队的方案。

对比维度容器内直接改 HTTPSNginx 反向代理统一终结 TLS
配置复杂度需要改容器内 Nginx 配置,且改完要重启容器只需要在宿主机写一份标准 Nginx server 配置
证书更新每次续期后都要重新挂载或重启容器在宿主机更新证书,reload Nginx 即可
多站点扩展一个容器锁死一个证书域名可以按 server_name 路由多个域名
升级 OnlyOffice 版本新镜像可能覆盖掉你的自定义配置容器保持默认,代理层不受影响
问题排查出问题要进容器里查日志链路清晰,宿主 Nginx 日志、容器日志分开看

所以在下面的实操环节,我默认采用“宿主机 Nginx 反向代理 + 容器保持 80 端口”的架构。这套方案我在 Ubuntu 20.04/22.04 和 CentOS 7 上都搭过,配置思路完全一致。

1.3 配置 HTTPS 涉及的关键技术点

先捋一下整个链路里的核心要素,避免后面操作时一头雾水:

  • TLS 证书:生产环境推荐 Let's Encrypt 免费证书或者云厂商的证书服务;内网测试可以用自签名证书;
  • Nginx 反向代理:监听 443,把/和/websocket请求转发到 OnlyOffice 容器;
  • WebSocket 代理:OnlyOffice 的协同编辑依赖 WebSocket 长连接,Nginx 必须正确配置 Upgrade 头;
  • X-Forwarded-Proto 请求头:让 OnlyOffice 内部知道客户端是通过 HTTPS 访问的,保证生成的下载、回调地址正确;
  • JWT 密钥:OnlyOffice 8.x 以后默认开启 JWT 校验,应用服务和文档服务必须保持一致。

这几个点里,WebSocket 和 X-Forwarded-Proto 是配置完 HTTPS 后最容易出问题的细节。很多同学只代理了常规的/路径,结果文档能打开但无法协同编辑;还有的改了 HTTPS 后文档地址正常了,但 OnlyOffice 生成的回调地址又变回了 HTTP,导致保存动作失败,问题就在转发头没设置完整。

2. 配置前的准备与信息梳理

2.1 确认 OnlyOffice 的部署形态

动手之前,先确认你手里的 OnlyOffice 是什么形态。目前最主流的是 Docker 安装的 Document Server,镜像名为onlyoffice/documentserver。也有不少人用 Linux 包直接安装在宿主机上,那种情况 Nginx 会直接占用 80 端口,你配置 HTTPS 的方式会稍微不同。

我用 Docker 部署的场景更多,所以下面的步骤以 Docker 部署为准。如果你是通过 RPM/DEB 包直接安装的,先把/etc/onlyoffice/documentserver/里的配置路径、Nginx 站点配置路径找到,核心思路仍然是再加一层 443 监听或修改默认站点配置。实际操作时,我建议先在浏览器里用http://服务器IP访问一次 OnlyOffice 首页,确认服务本身是健康的,再去搞 HTTPS。否则 HTTPS 配好了发现容器起不来,会干扰排查视线。

2.2 准备域名和证书

HTTPS 证书是绑定域名的。如果还在用裸 IP 访问,先决定一件事:你是否有域名可以把文档服务单独解析出来。强烈建议给 OnlyOffice 分配一个独立域名,比如doc.example.com,不要图省事和业务系统共用域名。独立域名在证书管理、故障隔离、跨域配置方面都省心得多。

证书获取有两条路:

  • 如果你有公网域名且服务器有公网 IP,用 Let's Encrypt 是最省钱的方案。装好certbot后,一条命令就能签发证书,还能配置自动续期。
  • 如果服务器只在内网使用,比如企业内网部署的 OA 系统,那可以用自签名证书。浏览器会提示“不安全”,但可以通过把证书导入到企业内部 CA 或各终端信任列表来消除告警。我个人在测试阶段也会用自签名证书,等正式上线前再换受信任的证书。

关于证书文件的路径,Nginx 配置时用到的是两个文件:证书公钥(.crt或.pem)和私钥(.key)。Let's Encrypt 签发的证书一般会存放在/etc/letsencrypt/live/你的域名/目录下,文件分别是fullchain.pem和privkey.pem。

2.3 梳理访问链路与会话流程

在配置前,你脑子里要有一条清晰的请求链路,否则出了问题很难定位。正常的访问流程是这样的:

  1. 用户打开业务系统页面,业务系统通过 HTTPS 加载https://doc.example.com/web-apps/apps/api/documents/api.js;
  2. 浏览器向doc.example.com:443发起请求;
  3. 宿主机 Nginx 接收请求,解密 TLS,转发到本地容器的127.0.0.1:80;
  4. OnlyOffice 容器处理请求,返回编辑页所需的 JS、CSS、HTML;
  5. 用户编辑文档时,OnlyOffice 再去请求编辑器的回调地址、协同服务地址、WebSocket 地址。

所以要保证整条链路里所有请求走的都是https://doc.example.com。任何一个环节出现 HTTP 或 IP 直连,浏览器就会出现混合内容或跨域问题。这也是为什么我总是强调:只有域名 + HTTPS 才能做到统一协议。

3. 实操:Nginx 反向代理与 HTTPS 配置

3.1 启动 OnlyOffice 容器的推荐参数

如果还没部署 OnlyOffice,下面是经过我多次实践后的一个可靠启动命令。注意端口映射我建议映射到回环地址,而不是直接-p 80:80,这样宿主机上的 Nginx 通过内网访问,不会把容器直接暴露到外网,安全性更好。

docker run -i -t -d \ --name onlyoffice-document-server \ --restart=always \ -e JWT_ENABLED=true \ -e JWT_SECRET=your-strong-secret-key \ -v /app/onlyoffice/logs:/var/log/onlyoffice \ -v /app/onlyoffice/data:/var/www/onlyoffice/Data \ -v /app/onlyoffice/lib:/var/lib/onlyoffice \ -v /app/onlyoffice/db:/var/lib/postgresql \ -p 127.0.0.1:80:80 \ onlyoffice/documentserver

这里有几个参数值得你注意:

  • JWT_SECRET:默认也是启用的,但如果之前用老版本没配置过,集成时尤其容易遇到“文档服务响应无效”之类的提示。务必记下这个密钥,后面集成业务系统时需要用到。
  • 数据目录挂载:Data、lib、db、logs四个目录是官方推荐要挂出来的,否则容器重建后证书、数据库、文档数据全部丢失。
  • 端口映射:我在宿主机 Nginx 配置里会把请求转发到127.0.0.1:80,所以这里映射的是回环地址。如果你图省事之前已经用了-p 80:80,那宿主机 Nginx 再监听 80 就会冲突。处理办法是调整映射端口,或者让 Nginx 直接监听 443 和另一个端口用于跳转,具体看你现场情况。

容器起来后,先用curl http://127.0.0.1测试一下能不能返回 HTML。能返回,说明 Each 层是好的。

3.2 编写 Nginx 反向代理配置

下面是我目前在生产环境使用的一份配置,去掉了无关的动静分离等花活,只保留核心内容,逻辑清晰,好排查。

# 用于将 HTTP 请求统一跳转到 HTTPS server { listen 80; server_name doc.example.com; # 证书自动续期时会用到 /.well-known 路径,要放行 location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://$host$request_uri; } } # HTTPS 正式入口 server { listen 443 ssl; http2 on; server_name doc.example.com; # 证书路径,根据实际环境调整 ssl_certificate /etc/letsencrypt/live/doc.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/doc.example.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; # 上传文档时文件可能比较大,限制设大一些 client_max_body_size 100m; # 超时时间适当放宽,文档转换大文件时不容易断 proxy_connect_timeout 600; proxy_read_timeout 600; proxy_send_timeout 600; location / { proxy_pass http://127.0.0.1:80; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; } # OnlyOffice 协同编辑依赖 WebSocket location /websocket { proxy_pass http://127.0.0.1:80/websocket; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 3600s; proxy_send_timeout 3600s; } }

配置里几个容易被忽略的细节,我逐个说明。

第一个是proxy_set_header X-Forwarded-Proto $scheme;。OnlyOffice 内部会根据这个头判断当前请求是 http 还是 https,继而生成正确的回调地址。我曾经建过没有加这个头的环境,结果 HTTPS 访问正常,但保存文档时回调地址写成http://,前端一直报“文档保存失败”,排查了很久才定位到是这个头缺失。

第二个是/websocket的代理。OnlyOffice 各版本的协同编辑模块都在这个路径下,必须把 WebSocket 升级请求原样转发。这里有两个要点:一是proxy_http_version必须设为 1.1,二是必须显式设置Upgrade和Connection头。如果你的在线编辑只是单机单用户,不用多人同时改一份文档,WebSocket 断了可能感知不明显;但只要两人同时编辑,就会立刻暴露。

第三个是proxy_buffering off;。老版本编辑文档时偶尔出现“文件上传失败”,和 Nginx 缓冲导致响应体被截断有关,关闭缓冲后这个问题就没有再出现过。

3.3 证书部署与 Nginx 验证流程

证书文件放到服务器后,记得先检查权限。Nginx 的 master 进程以 root 启动,但 worker 进程通常以 nginx 用户运行,证书私钥文件至少要保证能被 nginx 用户读取,否则 reload 时会报权限错误。一般做法是:

sudo chmod 755 /etc/letsencrypt/live/ sudo chmod 644 /etc/letsencrypt/live/doc.example.com/fullchain.pem sudo chmod 644 /etc/letsencrypt/live/doc.example.com/privkey.pem

配置写完后,先做语法检查:

nginx -t

看到syntax is ok和test is successful后再 reload:

systemctl reload nginx

这时从浏览器访问https://doc.example.com,正常情况下地址栏出现小锁,页面可以正常打开 OnlyOffice 文档编辑器的欢迎页或测试页。

3.4 用 curl 验证 HTTPS 链路

浏览器能访问只能说明基本通了,建议再用 curl 做几个级别的验证,可以快速定位问题在人、网络还是配置。

# 验证证书链和站点响应 curl -v https://doc.example.com/ # 验证 WebSocket 升级是否正常 curl -v -H "Connection: Upgrade" -H "Upgrade: websocket" \ -H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: SGVsbG9Xb3JsZGV2LmNvbQ==" \ https://doc.example.com/websocket

第一个命令能看出证书是否被信任、是否完整。第二个命令如果返回 101 Switching Protocols,说明 WebSocket 代理是通的。如果返回 200 或 4xx,大概率是 Nginx 没有正确识别 WebSocket 升级请求,去检查proxy_set_header Upgrade和Connection的配置。

4. 应用层联动:让在线编辑真正跑在 HTTPS 下

4.1 前端初始化时的配置修改

OnlyOffice 的编辑器前端初始化代码里,有一段类似这样的配置:

new DocsAPI.DocEditor("placeholder", { document: { fileType: "docx", key: "unique-key", title: "example.docx", url: "https://your-app.example.com/files/download" }, documentType: "word", editorConfig: { callbackUrl: "https://your-app.example.com/callback", lang: "zh-CN", user: { id: "user-001", name: "张三" } }, height: "700px", width: "100%" });

在 HTTPS 配置完成后,你要重点检查这里面的url和callbackUrl是不是以https://开头。很多项目里这个地址是后端动态拼接的,如果后端配置的协议还是 HTTP,那么即使用户通过 HTTPS 打开了页面,文档下载请求还是会发到 HTTP 地址,照样被浏览器拦截。

这里我建议后端在生成这些地址时,不要硬编码协议,而是直接读取当前请求的协议头和 Host,确保地址始终与页面保持一致。如果你用的是 Spring Boot、Java、.NET 这类框架,它们的工具类通常能根据X-Forwarded-Proto自动生成正确地址,前提是你已经在 Nginx 里把这个头设置对了。

4.2 JWT 校验与跨域配置

OnlyOffice 8.x 之后,Document Server 默认启用 JWT 鉴权。如果你在容器启动时通过环境变量设置了JWT_SECRET,那么在集成配置里也必须设置同样的密钥。有一种很常见的情况:你在部署时用了默认随机密钥,应用端又没同步,结果前端加载完编辑器后,任何文档操作都报错。解决方案就是统一密钥。

如果你不想用 JWT,可以直接在容器环境变量里加JWT_ENABLED=false。但我不建议生产环境这么干,因为 OnlyOffice 的服务端口通常会在内网暴露,没有鉴权的话任何人都可以调用转换接口,容易被滥用。

跨域的问题在 HTTPS 下反而简单了。因为前端页面和文档服务只要都是相同协议,就可以通过设置Access-Control-Allow-Origin来放行。Nginx 里可以加以下配置来解决一些跨域报错:

add_header Access-Control-Allow-Origin "https://your-app.example.com" always; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always; add_header Access-Control-Allow-Headers "Authorization, Content-Type, X-Requested-With" always;

不过要小心:如果 OnlyOffice 是给多个不同的业务系统共用,Access-Control-Allow-Origin写死一个域名会挡住其他来源。更稳妥的做法是只保持默认,通过 JWT 和网络策略来控制访问。

4.3 私网地址访问限制问题

这是一个非常隐蔽的坑,只在纯内网部署时会出现。OnlyOffice 出于安全考虑,默认不允许文档服务回调私网 IP或保留网段的地址。比如你的业务系统是http://192.168.1.100:8080,OnlyOffice 回调这个地址时会被它内部直接拒绝,界面上表现就是文档一直打不开或者保存失败。

在 OnlyOffice 较新的版本中,这个限制可以通过环境变量控制。启动容器时加入:

-e ALLOW_PRIVATE_IP_ADDRESS=true

如果你用的镜像版本没有这个环境变量,也可以去容器内修改/etc/onlyoffice/documentserver/local.json,把allowPrivateIPAddress改为true,然后重启容器或相关服务。但要注意:这个开关在生产公网环境下会有一定风险,开启前要确保 OnlyOffice 服务不对公网随意开放,最好只用防火墙限制来源 IP。

4.4 多语言与本地化配置

HTTPS 配好后,你会顺手遇到另一个高频问题:英文界面用着别扭,想改成中文。这个和 HTTPS 没有直接关系,但在做 OnlyOffice 集成时几乎是必配项。前端初始化时指定语言:

editorConfig: { lang: "zh-CN" }

服务端配置中,可以在容器环境变量里加-e LANGUAGE=zh-CN。不过实际我发现大多数项目是在前端配置里控制界面语言,服务端环境变量更多影响的是模板文档的语言。两个地方建议都设置成中文,避免用户看到的界面和系统语言不一致。

5. 常见问题与排查技巧实录

5.1 高频错误速查表

把我在实际运维中遇到的、以及社区里高频出现的问题整理成下表,每一行都对应一个实际症状,你可以照着快速定位,不用从头到尾扫日志。

症状可能原因排查方向
页面报 Mixed Content,编辑器白屏业务系统是 HTTPS,文档服务地址仍是 HTTP检查前端加载的 api.js 地址是否以 https 开头
文档能打开,但保存转圈回调地址是 HTTP 或不可达检查X-Forwarded-Proto、callbackUrl
多人协同编辑不生效WebSocket 代理未配置或配置错误检查 Nginx 的 /websocket location
编辑器提示“文档服务响应无效”JWT 密钥前后端不一致统一容器环境变量和应用端配置
转换大文件时超时Nginx 代理超时太短调大proxy_read_timeout、proxy_send_timeout
证书安装后浏览器提示不安全证书链不完整或自签名证书未信任使用 fullchain 证书,或将自签名证书加入系统信任库
容器和 Nginx 争抢 80 端口端口映射冲突构建-p 127.0.0.1:80:80的回环映射方式
OnlyOffice 无法访问内网系统私网地址限制设置ALLOW_PRIVATE_IP_ADDRESS=true

这张表我每次排查 OnlyOffice 问题时都会过一遍,大多数问题都能对号入座。

5.2 从日志入手的排查方法论

界面报错信息往往很模糊,真正有信息量的是日志文件。OnlyOffice 容器主要看这几个日志:

  • 容器访问错误日志:docker logs onlyoffice-document-server,可以看到请求到达情况;
  • OnlyOffice 自身日志:挂载目录/app/onlyoffice/logs/下的docservice、converter日志;
  • Nginx 宿主机访问日志:/var/log/nginx/access.log和error.log。

我在排查“保存失败”这类问题时,会先同时 tail 三份日志:宿主机 Nginx 日志、OnlyOffice 日志、业务系统日志。打开编辑页后做一次保存动作,观察请求是从哪一步断的:

  • 如果宿主机 Nginx 日志里根本没有/callback请求,说明前端没有发起回调,问题大概率在业务系统的回调地址或 JWT 校验;
  • 如果 Nginx 有请求但容器日志报 401 或签名错误,那就是密钥不一致;
  • 如果容器有请求但报连接超时,可能是文档服务器访问回调地址时网络不通,检查私网限制和防火墙。

这样一个链路一个环节地排除,比盲目改配置有效率得多。

5.3 罕见但坑人的几个细节

前面提到的都是高频问题,下面几个是我实际踩过、但网上很少详细说的细节,特别拿出来提醒你。

第一个是容器重建后数据丢失。如果你没有挂载数据卷,只是用docker run启动容器,后面因为升级或改配置重建容器,会发现文档数据、用户配置全部丢失,小则影响使用,大则造成工作成果丢失。我碰到过不止一次。所以部署 OnlyOffice 时一定要把数据和配置目录挂出来,这比 HTTPS 配置本身还重要。

第二个是证书自动续期后忘记 reload Nginx。Let's Encrypt 证书有效期是 90 天,certbot 自动续期成功后只是把新证书写到磁盘,Nginx 并不会自动加载新证书。如果续期后不systemctl reload nginx,在证书到期后的很长一段时间里,客户端访问会出现证书不匹配或直接无法连接。解决方法是配置一条--deploy-hook "systemctl reload nginx"的续期钩子,这个我在自动化脚本里加上后再没出过问题。

第三个是 IPv6 的坑。如果你的服务器开启了 IPv6,而 DNS 解析返回了 AAAA 记录,Nginx 默认只监听 IPv4 的 443 端口时,用户访问会长时间无法连接。遇到这种问题,检查 Nginx 的 listen 指令是否有[::]:443,没有的话加上,或者干脆把 DNS 的 AAAA 记录删掉,只保留 A 记录。这个坑很隐蔽,因为很多问题排查顺序是从证书、代理配置开始,很少有人会想到是 IPv6 监听问题。

第四个是 OnlyOffice 版本升级带来的配置变化。我在多个项目里从 7.x 升到 8.x 时,发现 JWT 默认启用策略有变化,原有的环境变量部分失效,导致集成方报错。升级前务必先看官方 Release Notes,尤其是关于环境变量、JWT、配置文件的变更说明,再决定升级步骤。

最后一个建议:把所有配置尽量都放到容器环境变量和 Nginx 配置里,不要靠每次启动后进容器手改配置文件。因为容器是临时的,重建后一切手工修改都会丢失。我自己的做法是写一份 docker-compose.yml 托管 OnlyOffice 和环境变量,Nginx 配置也放进版本控制,这样无论在哪台机器上重新部署,只要跑一遍 compose 和 Nginx 配置文件,环境就能完整复现。这个习惯帮我省了非常多重复排障的时间。

实际生产环境里,我还见过有人把 OnlyOffice 放在办公室内网,外部访问通过内网穿透到公网域名。这种场景下 HTTPS 配置思路是一样的,但要多注意内网穿透工具本身的 TLS 卸载和 Nginx 证书冲突问题。建议只在一层做 TLS 终结,不要层层加密、层层解密,否则问题会非常难以排查。我个人的体会是,OnlyOffice 配置 HTTPS 本身并不复杂,真正的复杂度在于你要对整个请求链路的每一跳都有数,从 DNS 到 Nginx,再到容器内服务,哪一层掉了链子都会表现为“文档打不开”。按本文的顺序把证书、代理、WebSocket、转发头都做对,再配合日志逐层排查,基本就能稳住了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询