Nginx 的 root 指令不支持直接使用变量(如 $host),因其在配置解析阶段要求路径为静态字符串;需通过 map 在 http 块中预定义动态路径变量,并在 server 块中引用 $dynamic_root 实现按域名映射目录。

Nginx 的 root 指令本身不支持直接使用变量(如 $host、${subdomain})作为路径值,在大多数上下文中,root 后面不能跟变量表达式。但通过合理组合 map、server_name 和 root,可以实现“动态 root 路径”的效果——即根据请求的域名或子域名,自动映射到不同物理目录。
为什么不能直接写 root /var/www/$host;
Nginx 在解析配置阶段就要求 root 的值是静态字符串(编译期确定),不支持运行时变量插值。若强行写成:
root /var/www/$host;
Nginx 会报错:nginx: [emerg] "root" directive invalid value "$host",或直接忽略变量、当作字面量处理(比如创建名为 $host 的子目录)。
用 map 实现子域名到目录的自动映射
这是最常用且可靠的方式,适用于多租户、多子站场景(如 a.example.com → /var/www/example/a)。
步骤一:在 http 块中定义 map 变量
http {
# 提取子域名部分(去掉主域名),例如 blog.example.com → blog
map $host $subdomain {
~^(?<s>[^.]+)\.example\.com$ $s;
~^(?<s>[^.]+\.[^.]+)\.example\.com$ $s;
default "";
}
# 将子域名转为路径格式,如 api.v2.dev → /api/v2/dev
map $host $docroot_path {
~^([^.]+)\.example\.com$ /$1;
~^([^.]+\.[^.]+)\.example\.com$ /$1;
~^([^.]+\.[^.]+\.[^.]+)\.example\.com$ /$1;
default "";
}
# 拼出完整 root 路径
map $docroot_path $dynamic_root {
~^/(.+)$ /var/www/example/$1;
default /var/www/example;
}
}⚠️ 注意:map 不支持嵌套正则捕获重用,所以建议用一个 map 完成全部逻辑,或用更健壮的写法(见下文)。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
步骤二:在 server 块中使用该变量
server {
listen 80;
server_name ~^(.+)\.example\.com$;
# ✅ 正确:root 可以引用 map 定义的变量(Nginx 1.11.1+ 支持)
root $dynamic_root;
index index.html;
}✅ 这种写法在较新版本 Nginx(≥1.11.1)中是合法且生效的,变量会在请求时动态求值。
替代方案:用 alias + rewrite(适合单层子域名)
如果只是简单区分 a.example.com 和 b.example.com,也可用 if + rewrite 配合 alias,但 if 在 location 中有局限,不推荐复杂逻辑:
server {
listen 80;
server_name ~^(?<sub>.+)\.example\.com$;
location / {
alias /var/www/example/$sub/;
index index.html;
try_files $uri $uri/ =404;
}
}⚠️ 注意:alias 和 root 拼接逻辑不同 —— alias 会替换匹配的 location 路径,而 root 是追加。此处 location / 匹配所有请求,alias /var/www/example/$sub/ 表示把 / 替换为该路径,因此访问 /style.css 实际查找 /var/www/example/$sub/style.css。
关键注意事项
-
root 后接变量仅在较新 Nginx 版本中支持,旧版本(如 1.10 或更早)会报错,需升级或改用
alias+map组合。 -
map必须定义在http块顶层,不能放在server或location内。 - 确保
$dynamic_root最终指向的路径真实存在,且 Nginx 工作进程(如www-data)有读取权限。 - 不要用
root /var/www/$host/;这类写法,它不会按预期工作,也不会报错,但会导致 404 或 403。
不复杂但容易忽略。

















