Nginx 如何在一个子域名下配置多个 location 指向不同的根目录?
在一个 server 块内写多个 location,各自指定 root 即可;注意 root 与 alias 的路径拼接差异、静态站 SPA 的 try_files、以及末尾斜杠问题。本文给出完整配置示例。
做法:在该子域名的 server 块内写多个 location 块,每个块用自己的 root(或 alias)指令指向不同目录。关键坑:root 会把 location 匹配的路径拼到目录后面**,alias 则是替换——两者混用最容易 404。**
完整配置示例
需求:sub.example.com/location1 由 /var/www/subdomain/location1 提供服务,/location2 同理。
server {
listen 80;
server_name sub.example.com;
location /location1 {
root /var/www/subdomain; # 实际文件在 /var/www/subdomain/location1/...
index index.html;
}
location /location2 {
alias /var/www/subdomain/location2; # 请求 /location2/a.css → /var/www/subdomain/location2/a.css
}
location / {
root /var/www/subdomain/main;
index index.html;
}
}
root 与 alias 的区别(核心坑)
| 指令 | 拼接规则 | 请求 /location1/style.css 时找的文件 |
|---|---|---|
root /var/www/subdomain; |
root + 完整 URI | /var/www/subdomain/location1/style.css |
alias /var/www/subdomain/location1/; |
alias 替换匹配前缀 | /var/www/subdomain/location1/style.css |
目录结构与 URI 一致时用 root;不一致时用 alias。
常见增强
前端 SPA 路由(history 模式刷新 404 问题):
location /app {
alias /var/www/frontend/dist/;
try_files $uri $uri/ /app/index.html;
}
末尾斜杠:location /app 不带斜杠时,/appxxx 也会被匹配到;想严格匹配写 location = /app 和 location /app/ 两条,或在入口做 301 补斜杠。
权限:确认 nginx 用户(www-data/nginx)对这些目录有读和执行(进入)权限。
验证流程
sudo nginx -t # 语法
sudo systemctl reload nginx # 生效
curl -I http://sub.example.com/location1/ # 实测
tail -f /var/log/nginx/error.log # 404 看这里的路径解析结果
error.log 里的 open() "/path/..." failed 会直接告诉你 Nginx 去哪个物理路径找了文件——路径拼错一眼可见。
观测云对照
多 location 的错误率分开看。 DataKit 采集 Nginx 日志后按 URI 前缀聚合,哪个 location 的 404/5xx 高、响应慢,在观测云看板各自成组,配置调整后效果立现。
常见问题(FAQ)
Q:location 匹配优先级是什么?
A:精确匹配 = > 前缀匹配(最长者优先)> 正则 ~ > 默认。前缀里 ^~ 可阻止继续匹配正则。
Q:两个 location 指向同一物理目录会有问题吗?
A:没问题,但多半说明该合并;alias 场景注意两个入口暴露的内容是否都该公开。
Q:alias 后面必须带斜杠吗?
A:location 以 / 结尾时 alias 也建议以 / 结尾,保证拼接正确;不写斜杠容易拼出 /pathfile.css 这种粘连路径。