DocumentRoot 是静态锚点,必须为无尾斜杠的绝对路径,不参与嵌套计算;它需真实存在、权限正确,并配套同路径的 <Directory> 授权,否则站点无法访问。

DocumentRoot 本身不参与多级目录嵌套的“计算”,它就是一个静态、独立、必须为绝对路径的指令,指向该虚拟主机的最顶层文件系统起点。所谓“多级目录嵌套”,其实是 <Directory> 块或 Alias 规则在 DocumentRoot 下进一步划分权限或映射路径——但 DocumentRoot 自身不会因为嵌套而动态变化或被“计算”出来。
换句话说:
✅ DocumentRoot 是你手动写死的、服务器上真实存在的一个完整路径;
❌ 它不是从 URL、子目录名、或上级配置“推导”或“拼接”出来的。
DocumentRoot 的路径写法要点(关键细节)
-
必须是绝对路径,开头带
/(Linux/macOS)或盘符(Windows),例如:/var/www/example.comC:/xampp/htdocs/myapp
末尾不能加斜杠(这是常见坑)
错误写法:DocumentRoot "/var/www/example.com/"
正确写法:DocumentRoot "/var/www/example.com"
原因:PHP 的$_SERVER['DOCUMENT_ROOT']、SSI 变量、路径拼接逻辑(如dirname(__FILE__))都依赖这个无尾斜杠格式,否则易引发双斜杠或相对路径错位。路径需真实存在且 Apache 进程有读取权限
比如属主应为www-data(Debian/Ubuntu)或apache(CentOS/RHEL),权限建议755,文件至少644。
多级嵌套中常见的混淆点(及正解)
当你看到类似这样的结构:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
<VirtualHost *:80>
DocumentRoot "/var/www/site1"
<Directory "/var/www/site1">
Require all granted
</Directory>
<Directory "/var/www/site1/admin">
Require ip 192.168.1.0/24
</Directory>
Alias "/static" "/srv/cdn/static"
</VirtualHost>注意:
-
/var/www/site1/admin是 DocumentRoot 下的一个子目录,但它不是新的 DocumentRoot,只是<Directory>授权控制的范围; -
<Directory>路径必须和文件系统实际路径完全一致(推荐绝对路径),它不“继承”或“补全”DocumentRoot; -
Alias "/static"是另一条独立路由,与 DocumentRoot 平级协作,不改变 DocumentRoot 的值,也不依赖它“计算”出物理路径。
如何确认你写的 DocumentRoot 是否生效?
- 打开 Apache 主配置或虚拟主机文件(如
/etc/apache2/sites-enabled/example.conf); - 查找
DocumentRoot行,确认路径拼写、无尾斜杠、权限可读; - 检查紧随其后的
<Directory "xxx">块是否匹配该路径,且含Require all granted; - 执行验证并重载:
sudo apache2ctl configtest # 或 httpd -t sudo systemctl reload apache2
- 访问
http://localhost/test.php,把test.php放在 DocumentRoot 对应目录下测试是否 404 —— 若 404,大概率路径不对或权限未开。
小结:DocumentRoot 就是“锚点”,不是“变量”
- 它不嵌套、不继承、不拼接、不计算;
- 所有子目录控制(
<Directory>)、别名映射(Alias)、重写规则(RewriteRule)都是以它为基准出发的; - 写对它,是整个站点能访问的第一前提;写错它,后面再精细的权限或路由都白搭。
不复杂,但容易忽略末尾斜杠和权限配套。

















