apache多站点托管必须为每个虚拟主机单独配置documentroot,因单个virtualhost内仅允许一个documentroot且不支持子目录动态切换;正确做法是用独立virtualhost隔离,错误做法包括重复定义documentroot或在directory/.htaccess中使用该指令。
直接为每个虚拟主机分配独立的 documentroot,是 apache 多站点托管的标准做法。关键不是“怎么设”,而是“必须用 virtualhost 隔离”——因为 apache 不允许一个 virtualhost 内有多个 documentroot,也不支持按子目录动态切换根路径。
每个虚拟主机配一个 DocumentRoot
DocumentRoot 指令只能出现在 <virtualhost></virtualhost> 块内(或全局服务器配置中),且每个块只允许出现一次。重复写会被忽略,Apache 启动时只认第一个。
- 正确写法:一个域名(或 IP+端口)对应一个
<virtualhost></virtualhost>,里面定义唯一的DocumentRoot - 错误尝试:在同一个
<virtualhost></virtualhost>里写两行DocumentRoot,第二行无效 - 错误尝试:在
<directory></directory>或.htaccess中写DocumentRoot,会报语法错误
基于域名的配置(最常用)
适用于多个域名共用同一 IP 和 80/443 端口,靠 HTTP 请求头中的 Host 字段区分路由。
- 确保主配置已启用虚拟主机加载,例如取消注释:
IncludeOptional sites-enabled/*.conf(Ubuntu/Debian)或Include conf/extra/httpd-vhosts.conf(CentOS/RHEL) - 在
/etc/apache2/sites-available/site-a.conf中写:
<virtualhost>
ServerName site-a.example.com
ServerAlias www.site-a.example.com
DocumentRoot "/var/www/site-a/public_html"
<directory>
Require all granted
</directory></virtualhost>
- 同理为 site-b.example.com 创建另一个
.conf文件,指向不同路径 - 启用配置:
sudo a2ensite site-a.conf && sudo systemctl reload apache2
基于端口或 IP 的补充方案
当无法使用域名(如开发环境无 DNS)、或需隔离更彻底时可选:
-
基于端口:在
ports.conf加Listen 8080,再建<virtualhost></virtualhost>,DocumentRoot指向另一目录 -
基于 IP:给服务器配多个 IP,每个
<virtualhost></virtualhost>对应一个 IP 和一个 DocumentRoot - 注意:基于端口访问需用户手动输
http://ip:8080;基于 IP 成本高,一般仅用于特殊场景
别把子目录当虚拟主机来用
如果只是想让 example.com/blog 指向另一目录,不要试图改 DocumentRoot —— 这属于路径映射,不是主机级分离:
- 用
Alias /blog "/var/www/blog"+<directory></directory>授权,适合静态或简单 PHP - 用
ProxyPass /api/ http://127.0.0.1:3000/转发到其他服务,适合前后端分离或微服务 - 所有这些都必须在同一个 VirtualHost 内完成,DocumentRoot 保持不变











