前言
虚拟主机(Virtual Host)是在一台服务器上托管多个网站的技术,通过Web服务器配置区分不同域名或IP的访问请求。无论是搭建个人博客、企业官网还是多站点平台,掌握虚拟主机配置都是必备技能。本文将详细介绍Apache和Nginx两种主流Web服务器的虚拟主机配置方法。
一、虚拟主机原理
1.1 什么是虚拟主机
虚拟主机允许一台物理服务器同时运行多个网站,每个网站拥有独立的域名、文档根目录和配置。
两种类型:
| 类型 | 区分依据 | 适用场景 |
|---|---|---|
| 基于域名(Name-based) | HTTP请求头中的Host字段 | 最常用,共享IP |
| 基于IP(IP-based) | 不同的IP地址 | 需要独立IP(如SSL证书) |
1.2 工作流程
用户访问 www.site-a.com
│
▼
DNS解析 → 服务器IP: 203.0.113.10
│
▼
Web服务器收到请求
读取Host头: www.site-a.com
│
▼
匹配虚拟主机配置
│
▼
返回 /var/www/site-a/ 目录下的内容
二、Apache虚拟主机配置
2.1 环境准备
# Ubuntu/Debian安装Apache
sudo apt update
sudo apt install apache2 php libapache2-mod-php -y
sudo systemctl enable apache2
sudo systemctl start apache2
# CentOS安装Apache
sudo yum install httpd php -y
sudo systemctl enable httpd
sudo systemctl start httpd
2.2 启用虚拟主机模块
# 启用vhost_alias模块
sudo a2enmod vhost_alias
sudo a2enmod rewrite
# 确认httpd-vhosts.conf被加载
# 编辑 /etc/apache2/apache2.conf,确保以下行未被注释:
# IncludeOptional sites-enabled/*.conf
2.3 创建网站目录结构
# 为两个站点创建目录
sudo mkdir -p /var/www/site-a/public_html
sudo mkdir -p /var/www/site-b/public_html
# 设置权限
sudo chown -R www-data:www-data /var/www/site-a
sudo chown -R www-data:www-data /var/www/site-b
sudo chmod -R 755 /var/www/site-a
sudo chmod -R 755 /var/www/site-b
# 创建测试页面
echo "<?php phpinfo(); ?>" | sudo tee /var/www/site-a/public_html/index.php
echo "<?php echo 'Site B Working!'; ?>" | sudo tee /var/www/site-b/public_html/index.php
2.4 配置虚拟主机
站点A配置: /etc/apache2/sites-available/site-a.conf
<VirtualHost *:80>
ServerName www.site-a.com
ServerAlias site-a.com
ServerAdmin admin@site-a.com
DocumentRoot /var/www/site-a/public_html
<Directory /var/www/site-a/public_html>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/site-a_error.log
CustomLog ${APACHE_LOG_DIR}/site-a_access.log combined
# PHP配置(可选)
php_value upload_max_filesize 20M
php_value post_max_size 25M
php_value max_execution_time 120
</VirtualHost>
站点B配置: /etc/apache2/sites-available/site-b.conf
<VirtualHost *:80>
ServerName www.site-b.com
ServerAlias site-b.com
ServerAdmin admin@site-b.com
DocumentRoot /var/www/site-b/public_html
<Directory /var/www/site-b/public_html>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/site-b_error.log
CustomLog ${APACHE_LOG_DIR}/site-b_access.log combined
</VirtualHost>
2.5 启用站点并重启
# 禁用默认站点(可选)
sudo a2dissite 000-default
# 启用新站点
sudo a2ensite site-a
sudo a2ensite site-b
# 测试配置语法
sudo apache2ctl configtest
# 重启Apache
sudo systemctl reload apache2
2.6 配置HTTPS(SSL)
# 安装Certbot
sudo apt install certbot python3-certbot-apache -y
# 为站点A申请证书
sudo certbot --apache -d www.site-a.com -d site-a.com
# 为站点B申请证书
sudo certbot --apache -d www.site-b.com -d site-b.com
# 自动续期已内置,验证定时任务
sudo certbot renew --dry-run
三、Nginx虚拟主机配置
3.1 安装Nginx + PHP-FPM
# Ubuntu/Debian
sudo apt install nginx php-fpm -y
sudo systemctl enable nginx php8.1-fpm
sudo systemctl start nginx php8.1-fpm
3.2 创建虚拟主机配置
站点A配置: /etc/nginx/sites-available/site-a
server {
listen 80;
server_name www.site-a.com site-a.com;
root /var/www/site-a/public_html;
index index.php index.html;
# 日志配置
access_log /var/log/nginx/site-a_access.log;
error_log /var/log/nginx/site-a_error.log;
# 主要location块
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP处理
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 120;
}
# 禁止访问隐藏文件
location ~ /\. {
deny all;
}
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
}
站点B配置: /etc/nginx/sites-available/site-b
server {
listen 80;
server_name www.site-b.com site-b.com;
root /var/www/site-b/public_html;
index index.php index.html;
access_log /var/log/nginx/site-b_access.log;
error_log /var/log/nginx/site-b_error.log;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\. {
deny all;
}
}
3.3 启用站点
# 创建软链接
sudo ln -s /etc/nginx/sites-available/site-a /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/site-b /etc/nginx/sites-enabled/
# 删除默认站点(可选)
sudo rm /etc/nginx/sites-enabled/default
# 测试配置
sudo nginx -t
# 重载Nginx
sudo systemctl reload nginx
3.4 配置HTTPS
# 安装Certbot Nginx插件
sudo apt install certbot python3-certbot-nginx -y
# 申请证书
sudo certbot --nginx -d www.site-a.com -d site-a.com
sudo certbot --nginx -d www.site-b.com -d site-b.com
四、Apache vs Nginx虚拟主机对比
| 对比项 | Apache | Nginx |
|---|---|---|
| 配置复杂度 | 较简单 | 中等 |
| 并发性能 | 中等(prefork/mpm_event) | 高(事件驱动) |
| PHP集成 | mod_php原生支持 | 需PHP-FPM |
| .htaccess | 原生支持 | 不支持(需转写规则) |
| 静态文件 | 性能一般 | 性能优异 |
| 反向代理 | 需mod_proxy | 原生支持 |
| 内存占用 | 较高 | 较低 |
| 适用场景 | 传统PHP应用、WordPress | 高并发、静态资源多 |
2026年推荐: 新项目优先选择Nginx,老项目或重度依赖.htaccess的项目可继续使用Apache。
五、本地测试配置
在部署到生产环境前,可以通过修改hosts文件进行本地测试:
# Linux/Mac: /etc/hosts
# Windows: C:\Windows\System32\drivers\etc\hosts
# 添加以下行
127.0.0.1 www.site-a.com
127.0.0.1 www.site-b.com
测试验证:
# 测试HTTP响应
curl -I http://www.site-a.com
curl -I http://www.site-b.com
# 测试PHP
curl http://www.site-a.com/index.php
curl http://www.site-b.com/index.php
六、安全加固
6.1 必做安全措施
# Apache安全配置
<Directory /var/www/>
Options -Indexes # 禁止目录列表
AllowOverride Limit # 限制.htaccess覆盖范围
ServerSignature Off # 隐藏服务器版本
</Directory>
# Nginx安全配置
server_tokens off; # 隐藏Nginx版本
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
6.2 PHP安全配置
; /etc/php/8.1/fpm/php.ini 安全相关
expose_php = Off # 隐藏PHP版本
display_errors = Off # 生产环境关闭错误显示
open_basedir = /var/www/ # 限制PHP访问目录
disable_functions = exec,passthru,shell_exec,system # 禁用危险函数
upload_max_filesize = 10M # 限制上传大小
post_max_size = 12M # 限制POST大小
七、常见问题解答
Q1:配置虚拟主机后访问显示默认页面?
A:检查以下几点:
1. 虚拟主机配置文件是否已启用(a2ensite/ln -s)
2. ServerName是否与请求域名匹配
3. DocumentRoot路径是否正确
4. 是否已重载Web服务器
Q2:Nginx如何实现Apache的.htaccess功能?
A:Nginx不支持.htaccess,需将重写规则直接写入server配置块。WordPress的Nginx重写规则已包含在3.2节的try_files指令中。
Q3:一个服务器最多能配置多少个虚拟主机?
A:理论上无硬性限制,实际取决于服务器硬件资源和并发流量。数百个低流量站点在一台4核8GB服务器上运行是常见的。
Q4:如何查看当前生效的虚拟主机配置?
A:
# Apache
apache2ctl -S # 列出所有虚拟主机
apache2ctl -D DUMP_VHOSTS
# Nginx
nginx -T # 输出完整配置
总结
配置PHP虚拟主机是Web运维的基础技能。Apache方案配置简单、生态成熟,适合传统PHP应用;Nginx方案性能优异、资源占用低,适合高并发场景。2026年,Nginx+PHP-FPM已成为新项目的主流选择,搭配Let’s Encrypt免费SSL证书和Certbot自动化工具,可以快速搭建安全可靠的多站点服务器。
注:本文基于2026年Apache 2.4和Nginx 1.24版本整理,具体配置路径可能因发行版不同而略有差异。