Apache不支持单个<VirtualHost>内用变量动态切换DocumentRoot,但可通过启用mod_vhost_alias模块、设置UseCanonicalName Off,并使用VirtualDocumentRoot指令实现基于域名的自动路径映射,配合通配<Directory>权限与PHP类型声明,达成多站点免手动配置的自动化部署。
不能在单个 <virtualhost> 内用变量“动态切换” documentroot,apache 不支持一个虚拟主机对应多个根目录。但可以通过 mod_vhost_alias 模块,在**虚拟主机层级实现基于请求域名的自动路径映射**,达到“开通即生效”的效果——无需每次新增站点都手动写一个 <virtualhost> 块。
启用 mod_vhost_alias 并关闭 CanonicalName
这是整套自动化方案的前提:
- 运行
a2enmod vhost_alias(Debian/Ubuntu)或确认LoadModule vhost_alias_module modules/mod_vhost_alias.so已在主配置中启用(RHEL/CentOS) - 在全局或
<VirtualHost>中添加:UseCanonicalName Off
这样 Apache 才会信任客户端发来的 Host 头,用于后续变量解析
用 VirtualDocumentRoot 替代 DocumentRoot
VirtualDocumentRoot 是 mod_vhost_alias 提供的专用指令,允许你在路径中嵌入变量(如 %0 表示完整域名,%1 表示第一级子域等):
- 基础写法示例:
VirtualDocumentRoot "/var/www/vhosts/%0"
访问shop.example.com→ 自动映射到/var/www/vhosts/shop.example.com/ - 更实用的分层结构:
VirtualDocumentRoot "/var/www/vhosts/%2+/%1"
访问blog.example.com→/var/www/vhosts/example.com/blog
访问api.myapp.dev→/var/www/vhosts/myapp.dev/api - 注意:
VirtualDocumentRoot只能在<VirtualHost>或服务器全局上下文中使用,不能写在<Directory>或 .htaccess 里
配套权限与 PHP 支持必须显式声明
自动映射只是路径层面的,目录访问控制和 PHP 解析仍需手动配置:
- 用通配符
<Directory "/var/www/vhosts/*">统一设置权限,避免逐站配置:Require all grantedAllowOverride All - 确保 PHP 模块已加载,并添加:
AddType application/x-httpd-php .php
否则所有 .php 文件会被当作纯文本下载 - 若站点用到重写规则(如 Laravel、WordPress),需在同级开启:
Options +FollowSymLinksRewriteEngine On
域名解析与本地测试要对齐
自动化依赖 Host 头精准匹配,任何偏差都会导致 404 或进错目录:
- 开发阶段:在
/etc/hosts中为每个待测域名加一行,例如:127.0.0.1 site1.local site2.local api.test.dev - 生产环境:DNS A 记录必须全部指向该服务器 IP,且无 CNAME 链跳转干扰 Host 头值
- ServerName 和 ServerAlias 不需要写——
VirtualDocumentRoot模式下它们被绕过;但<VirtualHost *:80>的端口监听必须存在且匹配

















