DocumentRoot 不支持嵌套或子路径覆盖,一个 VirtualHost 内只能定义一个,且作用于全部请求;多站点需独立 VirtualHost,子路径映射应使用 Alias 而非重复设置 DocumentRoot。

Apache 的 DocumentRoot 不能在“多级目录”中逐层覆盖上层路径——它不支持嵌套或继承式覆盖,而是按配置上下文严格生效:一个 VirtualHost 块内只能有一个 DocumentRoot,且它只作用于该虚拟主机的全部请求。
DocumentRoot 的作用范围是虚拟主机,不是目录层级
很多人误以为可以在 <Directory> 或子路径里再写 DocumentRoot 来“局部覆盖”,这是无效的。因为:
-
DocumentRoot的上下文仅限 服务器配置 和 VirtualHost,不能出现在<Directory>、<Location>或.htaccess中; - Apache 启动时会为每个
<VirtualHost>解析出唯一的根目录,所有请求(无论 URL 路径多深)都以这个根为起点拼接文件路径; - 试图在
<Directory "/var/www/app1">里再设DocumentRoot,Apache 会直接报错或忽略。
想实现“不同路径对应不同根目录”,该用 Alias 而不是 DocumentRoot
如果你的需求是:访问 /api/ 时从 /srv/backend/ 读文件,访问 /static/ 时从 /mnt/cdn/ 读文件,正确做法是保留主 DocumentRoot,再用 Alias 映射子路径:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 主站点仍用
DocumentRoot "/var/www/frontend"; - 添加
Alias /api "/srv/backend",并配套<Directory "/srv/backend">Require all granted</Directory>; - 添加
Alias /static "/mnt/cdn",同样配好对应<Directory>块; - 注意:Alias 规则优先于 DocumentRoot,所以
/api/index.php会命中别名路径,而非拼到主根下。
多个逻辑站点必须用多个 VirtualHost
如果“多级目录”实际指的是多个独立网站(比如 admin.example.com 和 blog.example.com),那不是目录问题,而是域名隔离问题:
- 每个域名定义一个
<VirtualHost *:80>块; - 各自设置不同的
DocumentRoot,如DocumentRoot "/var/www/admin"和DocumentRoot "/var/www/blog"; - 确保
ServerName正确,且 DNS 或 hosts 文件能解析到本机; - 不要把它们塞进同一个
DocumentRoot下再靠子目录区分——PHP 的__DIR__、框架路由、绝对路径引用都会混乱。
临时切换根目录的替代方案:符号链接 + 保持 DocumentRoot 不变
开发中常需快速切换内容源,又不想改配置重启,可借助文件系统层面的软链:
- 保持
DocumentRoot "/var/www/html"不变; - 把
/var/www/html指向当前要上线的目录,例如:sudo rm -f /var/www/htmlsudo ln -sf /srv/site-v2 /var/www/html; - 只要目标目录权限和 SELinux 上下文已就绪,切换立即生效,无需重载 Apache。

















