nginx 的 root 和 alias 指令本身不支持直接使用内置变量(如 $host、$uri)拼接路径,仅允许在正则 location 中引用 $1、$2 等捕获组;root 通过拼接 uri 实现路径定位,alias 则完全替换匹配前缀,动态映射需依赖 map 预定义变量或 rewrite + try_files 组合实现。

Nginx 的 root 和 alias 指令本身**不支持直接使用内置变量(如 $host、$uri、$1 等)拼接路径**。这不是配置写法问题,而是 Nginx 的设计限制:这两个指令只接受静态字符串或极有限的捕获变量(仅 $1、$2 等正则 location 中的捕获组),且不能参与字符串运算或条件拼接。
root 中用变量的正确方式:靠 map 预定义安全路径
想让不同域名或用户走不同根目录,不能写 root /var/www/$host;(会报错),而应在 http 块中用 map 提前把请求特征映射为确定路径:
- 用
map $host $site_root将域名转成预设路径,比如zh.example.com → /var/www/zh - 在
server块中写root $site_root;—— 此时$site_root是 map 计算出的纯字符串,不是运行时变量 - map 不支持复杂逻辑,但能做白名单式映射,兼顾安全与性能
alias 中用变量的可行场景:仅限正则 location 的捕获组
alias 允许引用 、 这类由 location ~ ... 捕获的变量,但必须严格匹配语义:
- location 必须带
~或~*启用正则,例如:location ~ ^/app/(\w+)/(.*)$ - alias 路径中可写
/opt/apps/$1/$2,其中$1是 app 名,$2是子路径 - alias 值末尾不能加
/(除非正则已捕获结尾斜杠),否则会导致路径错位 - 不能用
$uri、$request_uri等动态变量,它们在 alias 中无效
更灵活的替代方案:rewrite + root 或 try_files
当需要更复杂的路径逻辑(比如按参数、Header 或多层嵌套),推荐绕过 root/alias 直接拼接,改用重写驱动:
- 用
rewrite ^/u/(\w+)(/.*)?$ /$2 break;把/u/alice/css/app.css重写为/css/app.css - 配合
root /var/www/users/$1;(注意:这里$1是 rewrite 捕获的,但 root 本身仍不认它 —— 所以实际要用map配合 rewrite,或改用try_files) - 更稳妥的是
try_files $uri @fallback;+location @fallback内部用proxy_pass或再判断,避免路径拼错
关键区别再强调:root 拼接,alias 替换
理解行为本质比记语法更重要:
-
root /a; location /b/ { ... }→ 请求/b/file.txt查找/a/b/file.txt(拼接) -
alias /a/; location /b/ { ... }→ 请求/b/file.txt查找/a/file.txt(替换) - 混用正则和 alias 时,若 location 写成
^/b/(.*)$,alias 就必须对应/a/$1,且$1不能为空











