Nginx反向代理多域名核心在于Host头匹配与proxy_pass路径处理:server_name需精确或合理通配,proxy_pass末尾斜杠决定路径重写逻辑,HTTPS须为各域名配对应证书,且必须透传关键请求头与Cookie。

多个域名共用 80 端口做反向代理,本质不是“配置多个网站”,而是让 Web 服务器(如 Nginx)根据 Host 请求头把流量分发到不同后端服务。只要 server_name 匹配正确、proxy_pass 指向有效地址,就能跑通——但实际踩坑多在证书、路径重写和请求头透传上。
为什么 Nginx 的 server_name 必须精确匹配域名
Nginx 在收到请求时,只看 HTTP 请求行后的 Host 头,然后逐个比对所有 server 块里的 server_name。不匹配就走默认 server(通常是第一个或带 default_server 标志的)。
- 若配置了
server_name example.com;,但用户访问的是www.example.com,且没额外声明,请求会 404 或进错站点 - 支持通配符:
server_name *.example.com;匹配子域,但不匹配根域;server_name example.com www.example.com;是更稳妥的写法 - 本地测试时,记得改
/etc/hosts,否则 DNS 不解析,浏览器根本发不出带正确Host的请求
proxy_pass 后面加不加斜杠,彻底改变转发路径
这是最常导致 404 或资源加载失败的原因。Nginx 对 proxy_pass 末尾斜杠的处理逻辑非常严格:
-
proxy_pass http://127.0.0.1:3000;:原始请求路径完整保留,GET /api/users→ 转发给http://127.0.0.1:3000/api/users -
proxy_pass http://127.0.0.1:3000/;(末尾有/):会剥离 location 匹配的部分,location /api/ { proxy_pass http://127.0.0.1:3000/; }中,/api/users→http://127.0.0.1:3000/users - 如果后端服务本身不处理路径前缀(比如 Express 默认挂载在
/),却用了不带斜杠的proxy_pass,就可能把/admin/xxx错误地发成/admin/xxx给后端,而后端根本没注册这个路由
HTTPS 下必须为每个域名配独立 SSL 证书,不能靠 SNI “混用”
虽然现代浏览器和 Nginx 都支持 SNI(Server Name Indication),允许一个 IP 返回不同证书,但证书本身必须覆盖对应域名。Let’s Encrypt 的 certbot 支持批量申请:
certbot --nginx -d example.com -d www.example.com -d blog.example.com
- 不要试图用一个泛域名证书(
*.example.com)去 coverapi.other-site.com—— 证书校验直接失败,浏览器显示不安全 - Nginx 配置里每个
server块需明确指定自己的ssl_certificate和ssl_certificate_key,哪怕它们物理路径相同,也不能省略 - 若用自签名证书做内网测试,客户端(curl / 浏览器)必须显式信任,否则 TLS 握手阶段就断开,根本到不了反向代理逻辑
真正麻烦的从来不是“怎么写配置”,而是请求头是否透传、Cookie 的 Domain 和 Path 是否适配代理路径、WebSocket 升级头有没有加全——这些细节不调通,页面看似能打开,但登录态丢失、实时消息断连、静态资源 403,问题会分散在各处,很难归因。


















