CentOS7下Apache多VirtualHost配置失效问题求助
这个问题我太熟悉了——本质是Apache处理同端口、同ServerName虚拟主机的优先级规则在搞鬼!当你有多个<VirtualHost *:443>配置且它们的ServerName相同时,Apache会严格按照配置文件的加载顺序(按文件名字母排序,A10-my_site_dev.conf比A10-my_site_test.conf先被加载),把第一个匹配的VirtualHost作为该端口+ServerName的默认主机,后续的同类型VirtualHost会被直接忽略,这就是为什么你移除dev的配置后test站点能正常工作的原因。
下面给你两个实用的解决方案,按需选择:
方案1:合并配置到单个VirtualHost(最推荐)
既然两个站点是同一个域名下的不同路径(/my-site/dev和/my-site/test),完全没必要拆成两个VirtualHost。把所有配置整合到一个文件里,就能避免加载顺序的问题:
- 创建一个新的配置文件
/etc/httpd/conf.d/A10-my_site.conf,内容如下:
<VirtualHost *:443> # 可以设置统一的错误日志,也可以为每个站点单独配置(注意单个VirtualHost内多个ErrorLog会覆盖,建议用日志分割工具) ErrorLog "logs/my_site_combined.log" SSLCertificateFile /etc/ssl/host/host.crt SSLCertificateKeyFile /etc/ssl/host/host.key # Dev站点配置 Alias /my-site/dev/static /var/www/my_site_dev/static/ <Directory /var/www/my_site_dev/static> Require all granted </Directory> WSGIScriptAlias /my-site/dev /var/www/my_site_dev/app/wsgi.py <Directory /var/www/my_site_dev> Require all granted </Directory> # Test站点配置 Alias /my-site/test/static /var/www/my_site_test/static/ <Directory /var/www/my_site_test/static> Require all granted </Directory> WSGIScriptAlias /my-site/test /var/www/my_site_test/app/wsgi.py <Directory /var/www/my_site_test> Require all granted </Directory> </VirtualHost>
- 删除原来的两个配置文件:
rm /etc/httpd/conf.d/A10-my_site_dev.conf /etc/httpd/conf.d/A10-my_site_test.conf
- 重启Apache生效:
systemctl restart httpd
这样两个路径都会正常工作,因为它们都在同一个生效的VirtualHost块内。
方案2:移除VirtualHost,使用全局路径配置
你提到“不使用VirtualHost时所有配置均正常”,那可以直接去掉两个配置文件里的VirtualHost块,让路径配置全局生效:
- 修改
/etc/httpd/conf.d/A10-my_site_dev.conf,去掉VirtualHost包裹:
Alias /my-site/dev/static /var/www/my_site_dev/static/ <Directory /var/www/my_site_dev/static> Require all granted </Directory> WSGIScriptAlias /my-site/dev /var/www/my_site_dev/app/wsgi.py <Directory /var/www/my_site_dev> Require all granted </Directory>
- 修改
/etc/httpd/conf.d/A10-my_site_test.conf,同样去掉VirtualHost包裹:
Alias /my-site/test/static /var/www/my_site_test/static/ <Directory /var/www/my_site_test/static> Require all granted </Directory> WSGIScriptAlias /my-site/test /var/www/my_site_test/app/wsgi.py <Directory /var/www/my_site_test> Require all granted </Directory>
确保
ssl.conf里的<VirtualHost *:443>保留SSL证书配置(这样所有HTTPS请求都会使用这个SSL设置)。重启Apache:
systemctl restart httpd
这种方式下,Apache会加载所有全局的路径配置,不会受VirtualHost的加载顺序影响,两个站点自然都能访问。
为什么设置随机ServerName没用?
你尝试设置的my_site_test这类ServerName,和你实际请求的my-server.com不匹配——Apache会根据请求的Host头来匹配VirtualHost的ServerName/ServerAlias,你的请求Host是my-server.com,只会匹配到设置了这个ServerName的VirtualHost(也就是dev的那个),test的VirtualHost因为ServerName不匹配,根本不会被命中,所以还是会404。
内容的提问来源于stack exchange,提问作者Rom1

