Nginx配置proxy_pass实现子域名内容在主域名路径渲染
问题背景
我们运行搭载Nginx的PHP服务器,同时有一台Vercel托管的Next.js应用,已部署到子域名https://vercel.employbl.com/,域名由Cloudflare托管并通过CNAME记录关联Vercel。
需求是:用户访问https://www.employbl.com/jobs时,实际渲染https://vercel.employbl.com/jobs的内容,且保持employbl.com/jobs的URL不变。
当前Nginx配置如下:
location / { try_files $uri $uri/ /index.php?$query_string; } location /jobs { proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $http_host; proxy_pass https://vercel.employbl.com/jobs; }
但访问employbl.com/jobs时,Vercel返回404错误(错误码:DEPLOYMENT_NOT_FOUND),直接访问https://vercel.employbl.com/jobs则正常。
解决方案
问题根源在proxy_pass路径和Host头配置错误,调整后的正确配置如下:
修正后的/jobs location配置
location ^~ /jobs { proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host vercel.employbl.com; proxy_pass https://vercel.employbl.com; proxy_set_header X-Original-URI $request_uri; }
关键调整说明
调整
proxy_pass路径:
原配置中proxy_pass末尾带/jobs,会导致Nginx将原请求的/jobs路径叠加为/jobs/jobs转发给Vercel,不符合预期。去掉末尾的/jobs后,Nginx会完整转发原请求路径(如/jobs、/jobs/123)到Vercel服务器。修正
Host头:
原配置用$http_host传递主域名www.employbl.com给Vercel,但Vercel的部署绑定的是vercel.employbl.com,必须将Host头设置为该子域名,才能让Vercel匹配到对应的部署实例,避免返回DEPLOYMENT_NOT_FOUND。添加
X-Forwarded-Proto头:
该头告诉Vercel当前请求是通过HTTPS发起的,确保Next.js应用内部生成的URL使用正确的协议。用
location ^~ /jobs提高优先级:
这个匹配规则会让Nginx优先处理/jobs及其子路径的请求,避免被其他location规则(如根路径的PHP规则)干扰。
内容的提问来源于stack exchange,提问作者Connor Leech

