虚拟主机配置
虚拟主机概念
1. 什么是虚拟主机
虚拟主机允许在一台物理服务器上托管多个网站,每个网站可以有独立的域名、配置和内容。
虚拟主机类型
基于域名的虚拟主机:
- 通过不同域名区分网站
- 共享同一IP地址和端口
- 最常用的方式
基于IP的虚拟主机:
- 每个网站使用不同IP地址
- 需要多个IP地址
- 适用于SSL证书要求
基于端口的虚拟主机:
- 通过不同端口区分网站
- 共享同一IP地址
- 用户需要指定端口访问
基于域名的虚拟主机
1. 基本配置
单域名虚拟主机
server {
listen 80;
server_name example.com;
root /var/www/example.com;
index index.html index.php;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ =404;
}
}
多域名虚拟主机
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.php;
# 域名重定向
if ($host = www.example.com) {
return 301 http://example.com$request_uri;
}
location / {
try_files $uri $uri/ =404;
}
}
2. 通配符域名
前缀通配符
server {
listen 80;
server_name *.example.com;
root /var/www/subdomains;
# 使用变量设置根目录
set $subdomain "";
if ($host ~* "^(.+)\.example\.com$") {
set $subdomain $1;
}
root /var/www/subdomains/$subdomain;
location / {
try_files $uri $uri/ =404;
}
}
后缀通配符
server {
listen 80;
server_name example.*;
root /var/www/example;
location / {
try_files $uri $uri/ =404;
}
}
3. 正则表达式域名
正则匹配域名
server {
listen 80;
server_name ~^(?<subdomain>.+)\.example\.com$;
root /var/www/sites/$subdomain;
# 检查目录是否存在
if (!-d /var/www/sites/$subdomain) {
return 404;
}
location / {
try_files $uri $uri/ =404;
}
}
复杂正则匹配
server {
listen 80;
server_name ~^(www\.)?(?<domain>.+)$;
root /var/www/$domain;
# 自动www重定向
if ($host ~* "^www\.(.+)$") {
return 301 http://$1$request_uri;
}
location / {
try_files $uri $uri/ =404;
}
}
基于IP的虚拟主机
1. 多IP配置
不同IP的虚拟主机
# 第一个IP的网站
server {
listen 192.168.1.10:80;
server_name site1.example.com;
root /var/www/site1;
location / {
try_files $uri $uri/ =404;
}
}
# 第二个IP的网站
server {
listen 192.168.1.11:80;
server_name site2.example.com;
root /var/www/site2;
location / {
try_files $uri $uri/ =404;
}
}
2. IPv6支持
IPv6虚拟主机
server {
listen 80;
listen [::]:80;
server_name example.com;
root /var/www/example.com;
location / {
try_files $uri $uri/ =404;
}
}
基于端口的虚拟主机
1. 不同端口配置
多端口虚拟主机
# 主网站 - 端口80
server {
listen 80;
server_name example.com;
root /var/www/main;
location / {
try_files $uri $uri/ =404;
}
}
# 管理后台 - 端口8080
server {
listen 8080;
server_name example.com;
root /var/www/admin;
# 访问控制
allow 192.168.1.0/24;
deny all;
location / {
try_files $uri $uri/ =404;
}
}
# API服务 - 端口3000
server {
listen 3000;
server_name api.example.com;
location / {
proxy_pass http://localhost:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
默认服务器配置
1. 默认服务器设置
设置默认服务器
# 默认服务器 - 处理未匹配的请求
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# 返回444状态码(关闭连接)
return 444;
}
# 或者重定向到主站
server {
listen 80 default_server;
server_name _;
return 301 http://example.com$request_uri;
}
默认SSL服务器
server {
listen 443 ssl default_server;
server_name _;
ssl_certificate /etc/ssl/certs/default.crt;
ssl_certificate_key /etc/ssl/private/default.key;
return 444;
}
2. 错误页面配置
自定义错误页面
server {
listen 80;
server_name example.com;
root /var/www/example.com;
# 自定义错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /404.html {
root /var/www/errors;
internal;
}
location = /50x.html {
root /var/www/errors;
internal;
}
location / {
try_files $uri $uri/ =404;
}
}
高级虚拟主机配置
1. 条件配置
基于用户代理的配置
server {
listen 80;
server_name example.com;
# 移动设备重定向
if ($http_user_agent ~* "(Mobile|Android|iPhone|iPad)") {
return 301 http://m.example.com$request_uri;
}
root /var/www/example.com;
location / {
try_files $uri $uri/ =404;
}
}
基于地理位置的配置
# 需要安装GeoIP模块
http {
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
default no;
CN yes;
US yes;
JP yes;
}
}
server {
listen 80;
server_name example.com;
if ($allowed_country = no) {
return 403;
}
root /var/www/example.com;
location / {
try_files $uri $uri/ =404;
}
}
2. 动态虚拟主机
基于目录的动态虚拟主机
server {
listen 80;
server_name ~^(?<subdomain>.+)\.example\.com$;
set $root_path /var/www/sites/$subdomain;
# 检查目录是否存在
if (!-d $root_path) {
set $root_path /var/www/default;
}
root $root_path;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
# PHP处理
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
虚拟主机管理
1. 配置文件组织
站点配置结构
/etc/nginx/
├── nginx.conf # 主配置文件
├── sites-available/ # 可用站点配置
│ ├── example.com
│ ├── blog.example.com
│ └── api.example.com
├── sites-enabled/ # 启用的站点配置
│ ├── example.com -> ../sites-available/example.com
│ └── blog.example.com -> ../sites-available/blog.example.com
└── snippets/ # 配置片段
├── ssl-params.conf
└── fastcgi-php.conf
启用和禁用站点
# 启用站点
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# 禁用站点
sudo rm /etc/nginx/sites-enabled/example.com
# 测试配置
sudo nginx -t
# 重新加载配置
sudo systemctl reload nginx
2. 批量管理脚本
站点管理脚本
#!/bin/bash
# nginx-site-manager.sh
SITES_AVAILABLE="/etc/nginx/sites-available"
SITES_ENABLED="/etc/nginx/sites-enabled"
case "$1" in
enable)
if [ -f "$SITES_AVAILABLE/$2" ]; then
ln -s "$SITES_AVAILABLE/$2" "$SITES_ENABLED/"
echo "Site $2 enabled"
nginx -t && systemctl reload nginx
else
echo "Site $2 not found"
fi
;;
disable)
if [ -L "$SITES_ENABLED/$2" ]; then
rm "$SITES_ENABLED/$2"
echo "Site $2 disabled"
nginx -t && systemctl reload nginx
else
echo "Site $2 not enabled"
fi
;;
list)
echo "Available sites:"
ls -1 "$SITES_AVAILABLE"
echo
echo "Enabled sites:"
ls -1 "$SITES_ENABLED"
;;
*)
echo "Usage: $0 {enable|disable|list} [site-name]"
;;
esac
性能优化
1. 虚拟主机性能优化
连接优化
server {
listen 80;
server_name example.com;
root /var/www/example.com;
# 连接优化
keepalive_timeout 65;
keepalive_requests 100;
# 缓冲区优化
client_body_buffer_size 128k;
client_max_body_size 10m;
location / {
try_files $uri $uri/ =404;
}
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
}
2. 资源限制
限制配置
# 限制请求频率
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
listen 80;
server_name example.com;
root /var/www/example.com;
# 登录页面限制
location /login {
limit_req zone=login burst=3 nodelay;
try_files $uri $uri/ =404;
}
# API接口限制
location /api/ {
limit_req zone=api burst=20 nodelay;
proxy_pass http://backend;
}
location / {
try_files $uri $uri/ =404;
}
}
故障排除
1. 常见问题
域名解析问题
# 检查域名解析
nslookup example.com
dig example.com
# 检查本地hosts文件
cat /etc/hosts
# 测试连接
curl -H "Host: example.com" http://server_ip/
配置冲突问题
# 检查配置语法
nginx -t
# 查看配置详情
nginx -T
# 检查端口占用
netstat -tlnp | grep :80
ss -tlnp | grep :80
2. 调试技巧
调试配置
server {
listen 80;
server_name example.com;
# 调试信息
add_header X-Debug-Server-Name $server_name;
add_header X-Debug-Host $host;
add_header X-Debug-URI $request_uri;
root /var/www/example.com;
location / {
try_files $uri $uri/ =404;
}
}
总结
本课程详细介绍了Nginx虚拟主机的配置方法:
- 虚拟主机类型:基于域名、IP、端口的虚拟主机
- 域名匹配:精确匹配、通配符、正则表达式
- 默认服务器:处理未匹配请求的配置
- 高级配置:条件配置、动态虚拟主机
- 管理工具:配置组织、批量管理脚本
- 性能优化:连接优化、资源限制
下一课预告
在下一课中,我们将学习静态文件服务,包括:
- 静态文件托管配置
- 目录索引设置
- 文件下载优化
- 缓存策略配置
💡 小贴士:虚拟主机是Nginx的核心功能之一。合理的配置结构和命名规范有助于后期维护和管理。建议为每个站点创建独立的配置文件。
📚 文章对你有帮助?请关注我的公众号,万分感谢!
获取更多优质技术文章,第一时间掌握最新技术动态

关注公众号
第一时间获取最新技术文章

添加微信
技术交流 · 问题答疑 · 学习指导
评论讨论
欢迎留下你的想法和建议