Apache作为使用最广泛的Web服务器之一,其虚拟主机功能非常实用。所谓虚拟主机,就是让一台物理服务器同时承载多个网站,用户访问不同的域名时,Apache返回不同的站点内容。本文将以CentOS和Ubuntu两种常见环境为例,详细讲解虚拟主机的配置步骤,并整理配置过程中容易踩到的坑。

一、虚拟主机的三种实现方式
在动手配置之前,需要先理解Apache虚拟主机的三种类型,不同的类型适用于不同的场景,选错类型会导致配置不生效。
第一种是基于域名的虚拟主机(Name-based),这是目前最常用的方式。服务器只有一个IP地址,Apache根据请求头中的Host字段判断用户访问的是哪个域名,然后返回对应的站点内容。绝大多数个人站长和企业多站点部署都用这种方式。
第二种是基于IP的虚拟主机(IP-based),服务器上绑定多个IP地址,每个网站对应一个独立的IP。这种方式需要服务器拥有多个公网IP,成本较高,现在使用得越来越少,但在某些需要独立IP的场景(如SSL证书绑定)下仍有价值。
第三种是基于端口的虚拟主机(Port-based),通过不同的端口号区分站点,比如8080端口跑一个测试站,80端口跑正式站。这种方式不需要额外IP,但用户访问时必须在域名后面带上端口号,体验稍差,一般用于内网测试环境。
二、配置前的准备工作
开始配置之前,先确认Apache已经正确安装并能正常启动。在CentOS下安装命令为yum install httpd,在Ubuntu下则是apt install apache2。安装完成后用httpd -v或apache2 -v查看版本,确认服务可用。
接下来需要准备网站根目录。习惯上会在/var/www下为每个站点创建独立目录,例如为两个站点分别创建目录并放入测试页面:
mkdir -p /var/www/site1 mkdir -p /var/www/site2 echo "<h1>This is Site1</h1>" > /var/www/site1/index.html echo "<h1>This is Site2</h1>" > /var/www/site2/index.html
目录建好之后要确保Apache进程用户(通常是apache或www-data)对目录有读取权限,权限问题导致的403错误在后面会详细说明。
另外一点容易被忽略:如果你是在本地测试,需要修改本机hosts文件把测试域名指向服务器IP。Windows下hosts文件位于C:\Windows\System32\drivers\etc\hosts,Linux和macOS位于/etc/hosts,添加类似192.168.1.100 www.site1.com这样的记录即可。如果是生产环境,则需要到域名服务商处添加A记录解析。
三、基于域名的虚拟主机详细配置
这是最核心的部分。以CentOS为例,Apache的主配置文件在/etc/httpd/conf/httpd.conf,虚拟主机的独立配置文件在/etc/httpd/conf.d/目录下。Ubuntu则默认支持/etc/apache2/sites-available/和/etc/apache2/sites-enabled/两个目录配合使用。
首先确保主配置中加载了vhosts模块并监听了80端口。CentOS下编辑httpd.conf,找到下面这行并去掉前面的注释符号:
Listen 80 # 确认这行没有被注释 IncludeOptional conf.d/*.conf
Ubuntu下需要启用相关模块:
a2enmod vhost_alias systemctl restart apache2
然后在/etc/httpd/conf.d/vhosts.conf中写入虚拟主机配置,一个标准的配置段如下:
<VirtualHost *:80>
ServerAdmin webmaster@ipipp.com
ServerName www.site1.com
ServerAlias site1.com
DocumentRoot /var/www/site1
ErrorLog logs/site1_error.log
CustomLog logs/site1_access.log combined
<Directory /var/www/site1>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@ipipp.com
ServerName www.site2.com
DocumentRoot /var/www/site2
ErrorLog logs/site2_error.log
CustomLog logs/site2_access.log combined
<Directory /var/www/site2>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>配置中几个关键指令需要理解清楚。ServerName是这台虚拟主机的核心标识,Apache正是通过它来匹配请求的Host字段;ServerAlias用于配置额外域名,比如不带www的裸域名;DocumentRoot指定网站根目录;Directory配置段则控制对该目录的访问权限,其中Require all granted表示允许所有来源访问,这一点在Apache 2.4版本中必不可少,少了它几乎必然出现403错误。
写完配置后先测试语法再重启服务:
httpd -t systemctl reload httpd
如果httpd -t输出Syntax OK,说明配置没有语法问题。浏览器分别访问两个域名,看到不同的页面内容即代表配置成功。Ubuntu用户则是在sites-available下创建conf文件后,用a2ensite site1.conf启用站点,再执行systemctl reload apache2。
四、常见报错与排查思路
第一个高频问题是403 Forbidden。出现这个错误通常有三种原因:一是Directory段中缺少Require all granted,Apache 2.4与2.2的权限语法完全不同,网上很多老教程还写着Allow from all,直接照抄就会出问题;二是网站目录权限不足,可以用chmod -R 755 /var/www/site1修正;三是CentOS的SELinux限制,需要执行chcon -R -t httpd_sys_content_t /var/www/site1修改安全上下文。
第二个问题是访问任何域名都只显示第一个站点。这是因为Apache匹配不到对应的ServerName时会使用第一个虚拟主机作为默认站点。排查方向有两个:确认域名解析是否真的指向了这台服务器,可以在服务器上用ping命令验证;确认请求是否真的带Host头,早期的HTTP/1.0协议不带Host字段,现在浏览器基本不会出现这种问题,但用curl测试时建议加上-H参数显式指定。
第三个问题是端口冲突导致Apache启动失败,报类似Address already in use的错误。用netstat -tlnp | grep :80查看哪个进程占了端口,要么杀掉冲突进程,要么修改Apache的Listen端口。如果配置了基于端口的虚拟主机,别忘了防火墙要放行对应端口:firewall-cmd --add-port=8080/tcp --permanent && firewall-cmd --reload。
最后提醒一点,修改配置后推荐使用reload而不是restart,reload不会中断正在处理的连接,对线上服务更友好。配置完成后养成查看错误日志的习惯,日志文件的位置就写在VirtualHost配置里,遇到问题时先看日志往往比盲目搜索更高效。
Apache虚拟主机httpd-vhosts.conf虚拟主机配置修改时间:2026-09-16 18:32:43