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