如何正确合并两条Nginx规则?(Apache转Nginx+Discourse Docker场景)
嘿,我来帮你搞定这个Nginx规则合并的事儿!刚好之前我也处理过Discourse反向代理+子域名提取的场景,给你整理了一套完整的配置和说明:
完整Nginx配置方案
直接把下面的配置加到你的Nginx站点配置文件里(比如/etc/nginx/sites-available/domain.com),记得根据实际情况调整细节:
server { listen 80; listen [::]:80; server_name *.domain.com domain.com; # 先处理www子域名,统一重定向到不带www的版本 if ($host ~* ^www\.(.*)$) { return 301 $scheme://$1$request_uri; } # 提取非www的子域名,存到$subdomain变量(主域名访问时变量为空) set $subdomain ""; if ($host ~* ^([a-z0-9-]+)\.domain\.com$) { set $subdomain $1; } # 核心:处理/forum路径的反向代理和子域名追加 location /forum { # 如果有子域名,就把它追加到当前URL路径的末尾 if ($subdomain != "") { rewrite ^/forum(.*)$ /forum$1/$subdomain? permanent; } # 反向代理到Discourse Docker实例(替换成你的容器实际端口,比如8080) proxy_pass http://localhost:8080; # Discourse必需的代理头部,否则会有Cookie、跳转异常 proxy_set_header Host $http_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_set_header X-Forwarded-Port $server_port; # 优化代理性能的额外设置 proxy_redirect off; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_buffering off; client_max_body_size 100m; } # 可选:把根路径访问重定向到/forum,避免用户访问空页面 location / { return 301 $scheme://$host/forum; } }
关键配置说明
- server_name:匹配所有子域名(
*.domain.com)和主域名,确保能捕获所有访问请求 - www重定向:先把
www.xxx.domain.com这类请求重定向到xxx.domain.com,统一域名格式,避免子域名识别混乱 - 子域名提取:用正则表达式捕获主域名前的子域名部分,存到
$subdomain变量里;如果是主域名直接访问,这个变量为空 - forum路径处理:
- 当有子域名时,通过
rewrite规则把原路径(比如domain.com/forum/post/123)改成domain.com/forum/post/123/xxx(xxx是提取的子域名),用permanent表示301永久重定向,也可以换成last让Nginx内部处理不跳转 - 反向代理部分的头部配置是Discourse的刚需,缺少的话会导致登录失效、页面跳转错误等问题
- 当有子域名时,通过
注意事项
- 替换
localhost:8080为你Discourse Docker实例实际暴露的端口:比如你启动容器时用了-p 8080:80,这里就填8080;如果是用Docker网络连通,也可以直接填容器名+端口(比如discourse-app:80) - 要在Discourse后台开启反向代理信任:进入Discourse管理后台,找到“设置”→“安全”,开启“允许反向代理”选项,同时设置“反向代理IP地址”为你的Nginx服务器IP
- 配置完成后,用
nginx -t检查语法是否正确,没问题的话执行systemctl reload nginx让配置生效
内容的提问来源于stack exchange,提问作者MostHated
相关产品推荐
相关产品推荐

