如何配置Nginx Proxy Manager代理OnlyOffice Document Server Docker容器
Nginx Proxy Manager配置SSL后无法代理OnlyOffice问题排查与解决方案
问题描述
部署的Nginx Proxy Manager(以下简称NPM)在10月初之前使用默认配置代理OnlyOffice运行正常,当前使用通过DigitalOcean DNS挑战申请的Let's Encrypt通配符SSL证书后,OnlyOffice无法正常加载:移除SSL证书后服务恢复正常,添加SSL后浏览器访问示例编辑器报错或无响应,NextCloud的OnlyOffice连接器也无法建立连接。
现有配置
OnlyOffice Document Server docker-compose.yml
# ------------------------------------------------------------------------------ # OnlyOffice # # use port 80 with Nginx Proxy Manager # ------------------------------------------------------------------------------ version: "3" services: onlyoffice: container_name: onlyoffice domainname: mydomain.tdl environment: - JWT_ENABLED=true - JWT_SECRET=anAmazingSecretThatWillBlowYourMind - WOPI_ENABLED=true hostname: onlyoffice image: onlyoffice/documentserver networks: proxy_network: aliases: - onlyoffice restart: unless-stopped volumes: - ./config/onlyoffice/app:/var/lib/onlyoffice - ./config/onlyoffice/data:/var/www/onlyoffice/Data - ./config/onlyoffice/fonts:/usr/share/fonts/truetype/custom - ./config/onlyoffice/log:/var/log/onlyoffice - ./config/onlyoffice/postgresql:/var/lib/postgresql - ./config/onlyoffice/rabbitmq:/var/lib/rabbitmq - ./config/onlyoffice/redis:/var/lib/redis networks: proxy_network: external: true
Nginx Proxy Manager docker-compose.yml
# ------------------------------------------------------------------------------ # Nginx Proxy Manager # # use port 81 with Nginx Proxy Manager # ------------------------------------------------------------------------------ version: "3" services: nginxproxymanager: container_name: nginxproxymanager_app depends_on: - mariadb-aria domainname: mydomain.tdl environment: - DB_MYSQL_HOST=nginxproxymanager_db - DB_MYSQL_PORT=3306 - DB_MYSQL_USER=nginxproxymanager_user - DB_MYSQL_PASSWORD=TheMostSecurePas5w0rd - DB_MYSQL_NAME=nginxproxymanager_db - DISABLE_IPV6=true hostname: nginxproxymanager_app image: jc21/nginx-proxy-manager networks: default: aliases: - nginxproxymanager_app macvlan_network: aliases: - nginxproxymanager ipv4_address: www.xxx.yyy.zzz proxy_network: aliases: - nginxproxymanager restart: unless-stopped volumes: - ./config/data:/data - ./config/letsencrypt:/etc/letsencrypt mariadb-aria: container_name: nginxproxymanager_db domainname: mydomain.tdl environment: - MYSQL_ROOT_PASSWORD=EvenM0reSecurePas5w0rd - MYSQL_DATABASE=nginxproxymanager_db - MYSQL_USER=nginxproxymanager_user - MYSQL_PASSWORD=TheMostSecurePas5w0rd hostname: nginxproxymanager_db image: jc21/mariadb-aria networks: default: aliases: - nginxproxymanager_db restart: unless-stopped volumes: - /cache/nginxproxymanager/mariadb-aria:/var/lib/mysql networks: default: macvlan_network: external: true proxy_network: external: true
NPM自动生成的代理配置文件
# ------------------------------------------------------------ # onlyoffice.mydomain.tdl # ------------------------------------------------------------ server { set $forward_scheme http; set $server "onlyoffice"; set $port 80; listen 80; #listen [::]:80; listen 443 ssl http2; #listen [::]:443; server_name onlyoffice.mydomain.tdl; # Let's Encrypt SSL include conf.d/include/letsencrypt-acme-challenge.conf; include conf.d/include/ssl-ciphers.conf; ssl_certificate /etc/letsencrypt/live/npm-4/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/npm-4/privkey.pem; # Asset Caching include conf.d/include/assets.conf; # Block Exploits include conf.d/include/block-exploits.conf; # HSTS (ngx_http_headers_module is required) (63072000 seconds = 2 years) add_header Strict-Transport-Security "max-age=63072000;includeSubDomains; preload" always; # Force SSL include conf.d/include/force-ssl.conf; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; proxy_http_version 1.1; access_log /data/logs/proxy-host-44_access.log proxy; error_log /data/logs/proxy-host-44_error.log warn; location / { # HSTS (ngx_http_headers_module is required) (63072000 seconds = 2 years) add_header Strict-Transport-Security "max-age=63072000;includeSubDomains; preload" always; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; proxy_http_version 1.1; # Proxy! include conf.d/include/proxy.conf; } # Custom include /data/nginx/custom/server_proxy[.]conf; }
解决方案
按优先级依次排查修改:
- 补全转发头配置
默认NPM生成的配置没有传递X-Forwarded-Proto头,OnlyOffice无法识别前端访问为HTTPS协议,会返回HTTP资源链接,被浏览器混合内容策略拦截。
打开NPM对应OnlyOffice代理主机的「高级」选项卡,在自定义Nginx配置框中添加以下内容:
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; # 修复WebSocket连接异常 proxy_set_header Connection "upgrade"; # 禁用动态资源缓存,避免OnlyOffice的交互资源被错误缓存 proxy_ignore_headers Cache-Control; expires off;
保存后重载NPM配置即可。
修复重复HSTS配置
当前配置在server块和location块重复添加了HSTS头,部分浏览器会解析异常。在NPM的SSL设置页统一管理HSTS配置,删除location块中重复的HSTS配置项即可。调整OnlyOffice容器环境变量
在OnlyOffice的docker-compose.yml中添加以下环境变量,强制容器使用HTTP和NPM通信,避免内部协议协商错误:
- USE_UNSECURED_PORTS=true
修改后执行docker-compose up -d重启OnlyOffice容器。
- 验证证书有效性
进入NPM容器执行以下命令,确认证书的SAN字段包含onlyoffice.mydomain.tdl,且证书未过期、证书链完整:
openssl x509 -in /etc/letsencrypt/live/npm-4/fullchain.pem -text -noout
- 日志定位异常
如果以上修改仍未解决问题,查看三类日志定位具体错误:
- 浏览器控制台报错:确认是混合内容拦截、4xx权限错误还是5xx服务错误
- NPM错误日志:路径为
/data/logs/proxy-host-44_error.log,查看代理转发阶段的错误 - OnlyOffice容器日志:执行
docker logs onlyoffice查看服务内部运行错误
内容的提问来源于stack exchange,提问作者LordAdminChicken
相关产品推荐
相关产品推荐

