一、核心概念
Nginx多站点配置(虚拟主机)是指在一台Nginx服务器上运行多个独立网站。通过基于域名的虚拟主机或基于端口的虚拟主机实现资源复用。
| 虚拟主机类型 | 原理 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| 基于域名 | 通过server_name区分 |
多域名共享80/443端口 | 节省IP和端口 | 需要域名DNS解析 |
| 基于端口 | 通过listen端口区分 |
测试环境、内部系统 | 配置简单 | 需要记忆端口号 |
| 基于IP | 通过listenIP区分 |
多IP服务器 | 完全隔离 | 需要多个IP地址 |
二、准备工作
2.1 DNS解析设置
为每个域名添加A记录,指向服务器公网IP:
| 域名 | 记录类型 | 记录值 | TTL |
|---|---|---|---|
| blog.example.com | A | 192.168.1.100 | 600 |
| forum.example.com | A | 192.168.1.100 | 600 |
| api.example.com | A | 192.168.1.100 | 600 |
验证DNS解析:
# Windows
nslookup blog.example.com
# Linux/macOS
dig blog.example.com
ping blog.example.com
2.2 创建站点目录
# 创建站点根目录
sudo mkdir -p /var/www/blog
sudo mkdir -p /var/www/forum
sudo mkdir -p /var/www/api
# 创建测试页面
echo "<h1>Blog Site</h1>" | sudo tee /var/www/blog/index.html
echo "<h1>Forum Site</h1>" | sudo tee /var/www/forum/index.html
echo "<h1>API Site</h1>" | sudo tee /var/www/api/index.html
# 设置权限
sudo chown -R www-data:www-data /var/www/
sudo chmod -R 755 /var/www/
2.3 检查Nginx配置文件结构
# Ubuntu/Debian
ls -la /etc/nginx/
# 关键目录:
# - nginx.conf(主配置文件)
# - sites-available/(可用站点配置)
# - sites-enabled/(已启用站点配置)
# - conf.d/(额外配置)
# CentOS/RHEL
ls -la /etc/nginx/
# 关键目录:
# - nginx.conf(主配置文件)
# - conf.d/(站点配置目录)
三、基于域名的虚拟主机配置(推荐)
3.1 创建站点配置文件
方法1:在sites-available目录创建(Ubuntu/Debian)
sudo nano /etc/nginx/sites-available/blog.example.com
配置内容:
server {
listen 80;
listen [::]:80;
server_name blog.example.com;
root /var/www/blog;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ =404;
}
# PHP支持(可选)
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
# 日志配置
access_log /var/log/nginx/blog_access.log;
error_log /var/log/nginx/blog_error.log;
}
方法2:在conf.d目录创建(CentOS/RHEL)
sudo nano /etc/nginx/conf.d/blog.example.com.conf
配置内容同上。
3.2 启用站点(Ubuntu/Debian)
# 创建符号链接到sites-enabled
sudo ln -s /etc/nginx/sites-available/blog.example.com /etc/nginx/sites-enabled/
# 检查配置文件
sudo nginx -t
# 重载Nginx配置
sudo systemctl reload nginx
3.3 配置第二个站点
sudo nano /etc/nginx/sites-available/forum.example.com
配置内容:
server {
listen 80;
listen [::]:80;
server_name forum.example.com;
root /var/www/forum;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/forum_access.log;
error_log /var/log/nginx/forum_error.log;
}
启用站点:
sudo ln -s /etc/nginx/sites-available/forum.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
四、基于端口的虚拟主机配置
4.1 配置不同端口
sudo nano /etc/nginx/sites-available/port-8080.conf
配置内容:
server {
listen 8080;
listen [::]:8080;
server_name _; # 匹配所有域名
root /var/www/port-8080;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
4.2 配置多个端口
| 站点 | 端口 | 用途 |
|---|---|---|
| 主站 | 80/443 | 生产环境 |
| 测试站 | 8080 | 测试环境 |
| 管理后台 | 8081 | 内部系统 |
| API | 8082 | 接口服务 |
创建对应配置文件并启用。
4.3 防火墙开放端口
# Ubuntu(ufw)
sudo ufw allow 8080/tcp
sudo ufw allow 8081/tcp
sudo ufw allow 8082/tcp
sudo ufw reload
# CentOS(firewalld)
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=8081/tcp
sudo firewall-cmd --permanent --add-port=8082/tcp
sudo firewall-cmd --reload
五、HTTPS(SSL)配置
5.1 使用Let’s Encrypt免费证书
# 安装certbot
sudo apt update
sudo apt install certbot python3-certbot-nginx -y
# 为域名申请证书
sudo certbot --nginx -d blog.example.com -d www.blog.example.com
5.2 自动续期
# 测试自动续期
sudo certbot renew --dry-run
# 添加定时任务
sudo crontab -e
# 添加以下内容(每天凌晨2点检查续期)
0 2 * * * /usr/bin/certbot renew --quiet
5.3 HTTP强制跳转HTTPS
在server块中添加:
server {
listen 80;
listen [::]:80;
server_name blog.example.com www.blog.example.com;
return 301 https://$server_name$request_uri;
}
六、配置优化与最佳实践
6.1 日志管理
# 按日期切割日志
if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})") {
set $year $1;
set $month $2;
set $day $3;
}
access_log /var/log/nginx/$year-$month-$day_access.log combined;
6.2 缓存配置
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 365d;
add_header Cache-Control "public, immutable";
}
6.3 安全配置
# 隐藏Nginx版本号
server_tokens off;
# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;
# 防止MIME类型嗅探
add_header X-Content-Type-Options "nosniff" always;
# 防止XSS攻击
add_header X-XSS-Protection "1; mode=block" always;
6.4 性能优化
# 开启Gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 连接优化
keepalive_timeout 65;
keepalive_requests 100;
七、测试与调试
7.1 配置文件语法检查
# 检查Nginx配置文件语法
sudo nginx -t
# 输出示例(正确):
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
7.2 平滑重启Nginx
# 平滑重载配置(不中断服务)
sudo systemctl reload nginx
# 或
sudo nginx -s reload
# 重启Nginx服务
sudo systemctl restart nginx
7.3 查看Nginx状态
# 查看Nginx服务状态
sudo systemctl status nginx
# 查看监听端口
sudo netstat -tlnp | grep nginx
# 查看访问日志
sudo tail -f /var/log/nginx/access.log
# 查看错误日志
sudo tail -f /var/log/nginx/error.log
7.4 测试站点访问
# 本地测试
curl -I http://blog.example.com
curl -I http://forum.example.com
# 远程测试
# 在浏览器中访问:
# http://blog.example.com
# http://forum.example.com
八、常见问题排查
问题1:站点无法访问
排查步骤:
1. 检查DNS解析:dig blog.example.com
2. 检查Nginx是否运行:sudo systemctl status nginx
3. 检查防火墙:sudo ufw status
4. 检查配置文件:sudo nginx -t
5. 查看错误日志:sudo tail -f /var/log/nginx/error.log
问题2:server_name匹配错误
原因:多个server块匹配同一域名
解决方案:
# 精确匹配优先
server_name blog.example.com; # 精确匹配(优先级最高)
server_name *.example.com; # 通配符匹配
server_name ~^.*\.example\.com$; # 正则匹配(优先级最低)
问题3:端口冲突
排查:
# 查看端口占用
sudo netstat -tlnp | grep 80
sudo lsof -i :80
解决:修改listen端口或停止占用端口的服务。
问题4:403 Forbidden错误
原因:
1. 站点目录权限不正确
2. index文件不存在
3. SELinux策略限制(CentOS)
解决:
# 修复权限
sudo chown -R www-data:www-data /var/www/
sudo chmod -R 755 /var/www/
# 检查index文件
ls -la /var/www/blog/
# 临时关闭SELinux(CentOS)
sudo setenforce 0
九、多站点管理脚本
创建一键管理脚本:
#!/bin/bash
# nginx-site-manager.sh - Nginx多站点管理脚本
ACTION=$1
SITE_NAME=$2
case $ACTION in
create)
# 创建新站点
sudo mkdir -p /var/www/$SITE_NAME
echo "<h1>$SITE_NAME</h1>" | sudo tee /var/www/$SITE_NAME/index.html
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/$SITE_NAME
sudo sed -i "s/root .*/root \/var\/www\/$SITE_NAME;/" /etc/nginx/sites-available/$SITE_NAME
sudo sed -i "s/server_name .*/server_name $SITE_NAME;/" /etc/nginx/sites-available/$SITE_NAME
sudo ln -s /etc/nginx/sites-available/$SITE_NAME /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
echo "站点 $SITE_NAME 创建成功!"
;;
delete)
# 删除站点
sudo rm /etc/nginx/sites-enabled/$SITE_NAME
sudo rm /etc/nginx/sites-available/$SITE_NAME
sudo rm -rf /var/www/$SITE_NAME
sudo systemctl reload nginx
echo "站点 $SITE_NAME 删除成功!"
;;
list)
# 列出所有站点
ls -la /etc/nginx/sites-enabled/
;;
*)
echo "用法:$0 {create|delete|list} [site_name]"
exit 1
;;
esac
使用方法:
chmod +x nginx-site-manager.sh
sudo ./nginx-site-manager.sh create blog.example.com
sudo ./nginx-site-manager.sh list
sudo ./nginx-site-manager.sh delete blog.example.com
十、总结
Nginx多站点配置核心步骤:
- ✅ DNS解析设置(A记录指向服务器IP)
- ✅ 创建站点目录和测试页面
- ✅ 配置虚拟主机(基于域名或端口)
- ✅ 启用站点并测试配置
- ✅ 配置HTTPS(Let’s Encrypt)
- ✅ 优化性能和安全
- ✅ 设置日志管理和监控
通过以上步骤,您可以在一台Nginx服务器上成功运行多个独立站点,充分利用服务器资源。
注:本文基于Nginx 1.18+版本编写,适用于Ubuntu 20.04+/CentOS 7+系统。
常见问题快速参考
| 问题 | 解决方案 |
|---|---|
| 站点无法访问 | 检查DNS、Nginx状态、防火墙、配置文件 |
| 403 Forbidden | 检查目录权限、index文件、SELinux |
| 端口冲突 | 修改端口或停止占用服务 |
| SSL证书过期 | 运行certbot renew续期 |
| 配置不生效 | 运行nginx -t检查语法,然后systemctl reload nginx |