如何用Nginx反向代理实现多Mayan EDMS实例的URL路径映射?
Mayan EDMS 子路径部署问题解决方案
问题背景
已部署两个独立的Mayan EDMS Docker实例,直接访问地址分别为:
- 实例1:
http://192.168.1.42:49160 - 实例2:
http://192.168.1.42:49161
计划通过Nginx反向代理映射到以下子路径:
http://192.168.1.42:49152/one/→ 实例1http://192.168.1.42:49152/two/→ 实例2
当前映射后出现CSS失效、链接错误、404等问题,已尝试sub_filter和rewrite配置但未完全解决。
1. 是否可通过修改Nginx配置修复URL重写问题?具体需调整哪些内容?
可以,但需结合Nginx配置调整和Mayan EDMS环境变量配置,仅靠Nginx单方面配置无法彻底解决:
Nginx配置调整(default.conf)
补充路径前缀传递、完善内容替换规则,同时处理末尾斜杠的跳转:
server { listen 80 default_server; server_name _; # 传递必要的反向代理头,让Mayan识别真实请求的路径和协议 proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; # 关键:传递子路径前缀给Mayan应用 proxy_set_header X-Forwarded-Prefix "/one"; # 保留Websocket支持配置 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; # 处理/one和/one/的跳转,避免无斜杠访问时的404 location = /one { return 302 /one/; } location /one/ { proxy_pass http://host.docker.internal:49160/; # 全面替换页面中的绝对路径,覆盖更多属性 sub_filter '="/' '="/one/'; sub_filter '="http://' '="'; # 替换硬编码的绝对URL为相对路径 sub_filter_once off; sub_filter_types text/html text/css application/javascript; } # 实例2的配置逻辑与实例1完全一致 location = /two { return 302 /two/; } location /two/ { proxy_pass http://host.docker.internal:49161/; proxy_set_header X-Forwarded-Prefix "/two"; sub_filter '="/' '="/two/'; sub_filter '="http://' '="'; sub_filter_once off; sub_filter_types text/html text/css application/javascript; } }
Mayan EDMS环境变量调整
每个Mayan实例需添加以下环境变量(在Docker Compose中配置),让应用明确自身运行的子路径:
environment: - FORCE_SCRIPT_NAME=/one # 实例1填/one,实例2填/two - USE_X_FORWARDED_HOST=True - USE_X_FORWARDED_PORT=True - SECURE_PROXY_SSL_HEADER=HTTP_X_FORWARDED_PROTO,http
2. 是否因Mayan EDMS不支持子路径部署,导致无法实现该URL方案?
Mayan EDMS基于Django框架,原生支持子路径部署,之前的问题是因为未同时配置应用端的路径前缀和反向代理的头传递,导致应用生成的URL仍为根路径,与反向代理的子路径不匹配。
3. 若问题2答案为是,替代方案是否为使用子域名(如http://one.dms.example.org)?
即使子路径可行,子域名方案会更简单:
- Nginx只需为每个子域名配置独立的
server块,直接代理到对应Mayan实例端口即可,无需sub_filter和路径跳转逻辑。 - Mayan EDMS无需修改任何路径相关环境变量,直接按默认配置运行。
示例Nginx配置:
server { listen 80; server_name one.dms.example.org; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; location / { proxy_pass http://host.docker.internal:49160/; } } server { listen 80; server_name two.dms.example.org; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; location / { proxy_pass http://host.docker.internal:49161/; } }
4. Mayan EDMS已实现CSRF检测,该问题能否通过反向代理解决?
可以解决,核心是确保反向代理传递正确的头信息:
- 必须传递
Host头为用户访问的真实域名/IP(如192.168.1.42:49152或dms.example.org)。 - 若使用HTTPS,需传递
X-Forwarded-Proto为https;HTTP则为http。 - 配置Mayan的
SECURE_PROXY_SSL_HEADER环境变量,让应用识别反向代理传递的协议头。 - 子路径场景下,需确保
FORCE_SCRIPT_NAME配置正确,保证CSRF令牌的referer检查匹配子路径。
5. 除反向代理外,是否有其他解决方案?
在必须使用Docker的前提下,还有以下可选方案:
- 使用Traefik等现代化反向代理:Traefik支持Docker服务自动发现,可通过容器标签快速配置子路径或子域名映射,无需手动编写复杂的Nginx配置。
- 独立托管静态文件:将Mayan的静态文件单独挂载到Nginx,由Nginx直接提供静态文件服务,避免反向代理传递静态文件时的路径问题,但仍需配合应用端的路径前缀配置。
注:ORGANIZATIONS_INSTALLATION_URL仅用于组织模块的外部链接生成,并非全局路径配置,因此调整该变量无效,正确的全局路径配置是FORCE_SCRIPT_NAME。
内容的提问来源于stack exchange,提问作者Florian Wolters
相关产品推荐
相关产品推荐

