Nginx的root指令不支持直接使用变量,但可通过map预定义域名到路径的映射变量(如$site_root),再在server块中引用该变量作为root值,实现安全高效的多租户或虚拟主机静态资源动态映射。

Nginx 本身不支持在 root 指令中直接使用变量(如 $host、$subdomain)来动态指定物理路径,因为 root 是静态上下文指令,其值在配置加载阶段解析,而变量仅在请求处理阶段才可求值。但可以通过其他方式实现“按域名/路径动态映射物理目录”的效果。
用 alias + location 实现路径级动态映射
当需要根据 URI 路径(而非域名)区分站点时,可在 location 块中使用 alias,它支持变量(需注意结尾斜杠和路径拼接逻辑):
-
alias的值会被完整替换 location 匹配部分,且支持$1、$host等捕获变量 - 必须确保
alias路径以/结尾(除非匹配的是精确文件),否则易出 404 - 示例:将
/app1/映射到/var/www/app1/,/app2/映射到/var/www/app2/
配置片段:
location ~ ^/(app\d+)/(.*)$ {
alias /var/www/$1/$2;
try_files $uri $uri/ =404;
}用 map 预定义变量实现域名级 root 映射
这是最常用、最安全的多站点动态 root 方案。先用 map 指令建立域名到路径的映射表,再在 server 块中引用该变量:
-
map必须定义在http块顶层,不能嵌套在server或location内 - 支持正则匹配、通配符(如
*.example.com)和默认值(default) - 映射后的变量可在
root、fastcgi_param、proxy_pass等支持变量的指令中使用
配置片段:
http {
map $host $site_root {
hostnames;
default /var/www/default;
example.com /var/www/example;
blog.example.com /var/www/blog;
*.dev /var/www/dev/$host;
}
<pre class="brush:php;toolbar:false;">server {
listen 80;
server_name ~^(?<sub>.+)\.example\.com$ example.com;
root $site_root; # ✅ 变量在此处生效
index index.html;
}}
用 try_files + rewrite 辅助 fallback
当多个域名共享同一配置但需差异化响应时,可结合 try_files 尝试多个路径,或用 rewrite 重写 URI 后交由统一 root 处理:
-
try_files $uri $uri/ /index.html;常用于 SPA,但也可扩展为try_files $uri $uri/ /$host/index.html; -
rewrite可将请求重定向到带变量的内部路径,再配合alias或命名 location 使用 - 注意:rewrite 后若未加
last或break,可能引发循环或意外跳转
不推荐但可行:用 Lua 模块(OpenResty)做运行时 root 计算
若已部署 OpenResty,可通过 set_by_lua* 在请求阶段计算路径并赋值给变量,再用于 root:
- 需启用
ngx_http_lua_module,增加运维复杂度 - 性能开销略高,适合规则复杂、无法用
map表达的场景(如按数据库查路径) - 示例:
set_by_lua_block $dynamic_root { return "/var/www/" .. ngx.var.host:match("^(%w+)") }
普通 Nginx 安装默认不支持,不建议为简单多站点引入 Lua 依赖。


















