Apache 虚拟主机 #

虚拟主机概述 #

什么是虚拟主机? #

text
┌─────────────────────────────────────────────────────────────┐
│                    虚拟主机概念                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  虚拟主机允许一台服务器托管多个网站                          │
│                                                             │
│  传统方式:一个网站 = 一台服务器                             │
│  ┌─────────┐                                                │
│  │ 网站 A  │ ──> 服务器 1                                   │
│  └─────────┘                                                │
│  ┌─────────┐                                                │
│  │ 网站 B  │ ──> 服务器 2                                   │
│  └─────────┘                                                │
│                                                             │
│  虚拟主机:多个网站 = 一台服务器                             │
│  ┌─────────┐                                                │
│  │ 网站 A  │ ──┐                                            │
│  └─────────┘   │                                            │
│  ┌─────────┐   ├──> 同一台服务器                            │
│  │ 网站 B  │ ──┤                                            │
│  └─────────┘   │                                            │
│  ┌─────────┐   │                                            │
│  │ 网站 C  │ ──┘                                            │
│  └─────────┘                                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

虚拟主机类型 #

text
┌─────────────────────────────────────────────────────────────┐
│                    虚拟主机类型                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 基于名称的虚拟主机(最常用)                             │
│     - 一个 IP 地址,多个域名                                 │
│     - 通过 Host 头区分                                      │
│     - 节省 IP 资源                                          │
│                                                             │
│  2. 基于 IP 的虚拟主机                                      │
│     - 每个 IP 对应一个网站                                   │
│     - 需要多个 IP 地址                                      │
│     - 适合 SSL 证书要求                                     │
│                                                             │
│  3. 基于端口的虚拟主机                                      │
│     - 同一 IP,不同端口                                      │
│     - 适合开发测试环境                                      │
│     - 不适合生产环境                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

基于名称的虚拟主机 #

工作原理 #

text
┌─────────────────────────────────────────────────────────────┐
│                    基于名称的虚拟主机                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  客户端请求:                                               │
│  GET / HTTP/1.1                                             │
│  Host: site1.com                                            │
│                                                             │
│  Apache 处理:                                              │
│  1. 接收请求                                                │
│  2. 解析 Host 头                                            │
│  3. 匹配 ServerName                                         │
│  4. 返回对应网站内容                                        │
│                                                             │
│  ┌─────────┐                                                │
│  │ site1.com│ ──┐                                            │
│  └─────────┘   │     ┌─────────────────┐                    │
│                ├────>│ Apache Server   │                    │
│  ┌─────────┐   │     │ 192.168.1.100   │                    │
│  │ site2.com│ ──┘     └─────────────────┘                    │
│  └─────────┘                                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

基础配置 #

apache
# ============================================
# 基于名称的虚拟主机配置
# ============================================

# Ubuntu/Debian: /etc/apache2/sites-available/site1.conf
# CentOS/RHEL: /etc/httpd/conf.d/site1.conf

# 网站 1
<VirtualHost *:80>
    ServerName site1.com
    ServerAlias www.site1.com
    DocumentRoot /var/www/site1
    
    <Directory /var/www/site1>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/site1-error.log
    CustomLog ${APACHE_LOG_DIR}/site1-access.log combined
</VirtualHost>

# 网站 2
<VirtualHost *:80>
    ServerName site2.com
    ServerAlias www.site2.com
    DocumentRoot /var/www/site2
    
    <Directory /var/www/site2>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/site2-error.log
    CustomLog ${APACHE_LOG_DIR}/site2-access.log combined
</VirtualHost>

默认虚拟主机 #

apache
# ============================================
# 默认虚拟主机配置
# ============================================

# 默认虚拟主机(匹配所有未指定的域名)
<VirtualHost _default_:80>
    ServerName localhost
    DocumentRoot /var/www/default
    
    # 可以返回 404 或重定向
    # Redirect 404 /
    
    <Directory /var/www/default>
        Options -Indexes
        Require all granted
    </Directory>
</VirtualHost>

# 或使用 * 作为第一个虚拟主机
<VirtualHost *:80>
    ServerName default
    DocumentRoot /var/www/default
</VirtualHost>

ServerName 和 ServerAlias #

apache
# ============================================
# ServerName 和 ServerAlias 配置
# ============================================

<VirtualHost *:80>
    # 主域名
    ServerName example.com
    
    # 别名(可以有多个)
    ServerAlias www.example.com
    ServerAlias example.net www.example.net
    ServerAlias *.example.com    # 通配符
    
    DocumentRoot /var/www/example
    
    <Directory /var/www/example>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

基于 IP 的虚拟主机 #

工作原理 #

text
┌─────────────────────────────────────────────────────────────┐
│                    基于 IP 的虚拟主机                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  每个网站绑定不同的 IP 地址                                  │
│                                                             │
│  ┌─────────┐                                                │
│  │ site1.com│ ──> 192.168.1.100                            │
│  └─────────┘         │                                      │
│                      │     ┌─────────────────┐              │
│                      ├────>│ Apache Server   │              │
│  ┌─────────┐         │     │                 │              │
│  │ site2.com│ ──> 192.168.1.101              │              │
│  └─────────┘               └─────────────────┘              │
│                                                             │
│  配置 IP 别名:                                             │
│  ip addr add 192.168.1.101/24 dev eth0                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

配置示例 #

apache
# ============================================
# 基于 IP 的虚拟主机配置
# ============================================

# 监听多个 IP 地址
Listen 192.168.1.100:80
Listen 192.168.1.101:80

# 网站 1(IP 1)
<VirtualHost 192.168.1.100:80>
    ServerName site1.com
    DocumentRoot /var/www/site1
    
    <Directory /var/www/site1>
        Options -Indexes +FollowSymLinks
        Require all granted
    </Directory>
</VirtualHost>

# 网站 2(IP 2)
<VirtualHost 192.168.1.101:80>
    ServerName site2.com
    DocumentRoot /var/www/site2
    
    <Directory /var/www/site2>
        Options -Indexes +FollowSymLinks
        Require all granted
    </Directory>
</VirtualHost>

基于端口的虚拟主机 #

工作原理 #

text
┌─────────────────────────────────────────────────────────────┐
│                    基于端口的虚拟主机                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  同一 IP 地址,不同端口                                      │
│                                                             │
│  ┌──────────────────┐                                       │
│  │ example.com:80   │ ──> 主站点                            │
│  └──────────────────┘                                       │
│  ┌──────────────────┐     ┌─────────────────┐              │
│  │ example.com:8080 │ ───>│ Apache Server   │              │
│  └──────────────────┘     │ 192.168.1.100   │              │
│  ┌──────────────────┐     └─────────────────┘              │
│  │ example.com:443  │ ──> HTTPS 站点                       │
│  └──────────────────┘                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

配置示例 #

apache
# ============================================
# 基于端口的虚拟主机配置
# ============================================

# 监听多个端口
Listen 80
Listen 8080
Listen 8443

# 主站点(端口 80)
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/main
    
    <Directory /var/www/main>
        Options -Indexes +FollowSymLinks
        Require all granted
    </Directory>
</VirtualHost>

# 管理后台(端口 8080)
<VirtualHost *:8080>
    ServerName admin.example.com
    DocumentRoot /var/www/admin
    
    <Directory /var/www/admin>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require ip 192.168.1.0/24
    </Directory>
</VirtualHost>

# 开发环境(端口 8443)
<VirtualHost *:8443>
    ServerName dev.example.com
    DocumentRoot /var/www/dev
    
    <Directory /var/www/dev>
        Options -Indexes +FollowSymLinks
        Require ip 192.168.1.0/24
    </Directory>
</VirtualHost>

虚拟主机管理 #

Ubuntu/Debian 站点管理 #

bash
# ============================================
# Ubuntu/Debian 虚拟主机管理
# ============================================

# 创建站点配置文件
sudo nano /etc/apache2/sites-available/example.com.conf

# 启用站点
sudo a2ensite example.com.conf

# 禁用站点
sudo a2dissite example.com.conf

# 测试配置
sudo apache2ctl configtest

# 重载配置
sudo systemctl reload apache2

# 查看已启用站点
ls /etc/apache2/sites-enabled/

CentOS/RHEL 站点管理 #

bash
# ============================================
# CentOS/RHEL 虚拟主机管理
# ============================================

# 创建站点配置文件
sudo nano /etc/httpd/conf.d/example.com.conf

# 测试配置
sudo httpd -t

# 重载配置
sudo systemctl reload httpd

# 查看已加载配置
ls /etc/httpd/conf.d/

查看虚拟主机配置 #

bash
# 查看虚拟主机配置
sudo apachectl -S

# 输出示例
# VirtualHost configuration:
# *:80                   is a NameVirtualHost
#          default server localhost (/etc/apache2/sites-enabled/000-default.conf:1)
#          port 80 namevhost localhost (/etc/apache2/sites-enabled/000-default.conf:1)
#          port 80 namevhost example.com (/etc/apache2/sites-enabled/example.com.conf:1)
#                  alias www.example.com
#          port 80 namevhost site2.com (/etc/apache2/sites-enabled/site2.conf:1)

完整配置示例 #

企业网站配置 #

apache
# ============================================
# 企业网站完整配置
# ============================================

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    ServerAdmin webmaster@example.com
    DocumentRoot /var/www/example/public
    
    # 目录配置
    <Directory /var/www/example/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
        
        DirectoryIndex index.html index.php
    </Directory>
    
    # 禁止访问敏感目录
    <Directory /var/www/example/private>
        Require all denied
    </Directory>
    
    # 日志配置
    ErrorLog ${APACHE_LOG_DIR}/example-error.log
    CustomLog ${APACHE_LOG_DIR}/example-access.log combined
    
    # 错误页面
    ErrorDocument 404 /404.html
    ErrorDocument 500 /500.html
    
    # 安全配置
    ServerSignature Off
    ServerTokens Prod
    
    # 隐藏敏感文件
    <FilesMatch "^\.">
        Require all denied
    </FilesMatch>
</VirtualHost>

多域名配置 #

apache
# ============================================
# 多域名配置示例
# ============================================

# 主域名
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example
</VirtualHost>

# 子域名 - 博客
<VirtualHost *:80>
    ServerName blog.example.com
    DocumentRoot /var/www/blog
</VirtualHost>

# 子域名 - API
<VirtualHost *:80>
    ServerName api.example.com
    DocumentRoot /var/www/api
</VirtualHost>

# 子域名 - 静态资源
<VirtualHost *:80>
    ServerName static.example.com
    DocumentRoot /var/www/static
</VirtualHost>

# 通配符子域名
<VirtualHost *:80>
    ServerName users.example.com
    ServerAlias *.users.example.com
    DocumentRoot /var/www/users
</VirtualHost>

开发环境配置 #

apache
# ============================================
# 开发环境配置
# ============================================

# 开发站点
<VirtualHost *:80>
    ServerName dev.example.com
    DocumentRoot /var/www/dev
    
    <Directory /var/www/dev>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require ip 192.168.1.0/24
        
        # 开发环境允许目录列表
        # Options +Indexes
        
        # 显示 PHP 错误
        php_flag display_errors on
        php_value error_reporting E_ALL
    </Directory>
    
    # 详细日志
    LogLevel debug
    ErrorLog ${APACHE_LOG_DIR}/dev-error.log
    CustomLog ${APACHE_LOG_DIR}/dev-access.log combined
</VirtualHost>

# 测试站点
<VirtualHost *:80>
    ServerName test.example.com
    DocumentRoot /var/www/test
    
    <Directory /var/www/test>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require ip 192.168.1.0/24
    </Directory>
</VirtualHost>

虚拟主机调试 #

常见问题排查 #

text
┌─────────────────────────────────────────────────────────────┐
│                    常见问题                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 访问显示默认页面                                        │
│     原因:ServerName 不匹配                                 │
│     解决:检查域名解析和 ServerName 配置                     │
│                                                             │
│  2. 403 Forbidden                                           │
│     原因:目录权限问题                                      │
│     解决:检查 Directory 配置和文件权限                      │
│                                                             │
│  3. 配置不生效                                              │
│     原因:未启用站点或未重载                                │
│     解决:a2ensite + reload                                 │
│                                                             │
│  4. 多个域名指向同一网站                                    │
│     原因:ServerAlias 配置错误                              │
│     解决:检查 ServerAlias 配置                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

调试命令 #

bash
# 查看虚拟主机配置
sudo apachectl -S

# 测试配置语法
sudo apachectl configtest

# 查看错误日志
sudo tail -f /var/log/apache2/error.log

# 测试域名解析
dig example.com
nslookup example.com

# 测试 HTTP 请求
curl -I http://example.com
curl -H "Host: example.com" http://192.168.1.100/

下一步 #

掌握了虚拟主机配置后,继续学习 反向代理,了解如何使用 Apache 作为反向代理服务器!

最后更新:2026-03-29