一台搬瓦工VPS可以同时托管多个网站,通过Nginx的Server Block(虚拟主机)功能实现。不同域名指向同一IP,Nginx根据请求的域名将流量路由到对应的网站目录或后端服务。本文介绍完整的多站点配置方法。
为每个站点创建独立的网站目录和日志目录:
# 创建网站根目录
sudo mkdir -p /var/www/site-a.com/html
sudo mkdir -p /var/www/site-b.com/html
sudo mkdir -p /var/www/site-c.com/html
# 创建日志目录
sudo mkdir -p /var/log/nginx/site-a.com
sudo mkdir -p /var/log/nginx/site-b.com
sudo mkdir -p /var/log/nginx/site-c.com
# 设置目录权限
sudo chown -R www-data:www-data /var/www/
sudo chmod -R 755 /var/www/
为每个站点创建一个测试页面:
echo "<h1>Site A</h1>" | sudo tee /var/www/site-a.com/html/index.html
echo "<h1>Site B</h1>" | sudo tee /var/www/site-b.com/html/index.html
echo "<h1>Site C</h1>" | sudo tee /var/www/site-c.com/html/index.html
每个站点使用独立的配置文件,便于管理和维护。Nginx有两种配置文件组织方式:
方式一:conf.d 目录(推荐)
# Debian/Ubuntu/CentOS 默认加载 conf.d 目录下的 .conf 文件
# 在 /etc/nginx/nginx.conf 中已有:
# include /etc/nginx/conf.d/*.conf;
# 为每个站点创建配置文件
sudo nano /etc/nginx/conf.d/site-a.com.conf
sudo nano /etc/nginx/conf.d/site-b.com.conf
sudo nano /etc/nginx/conf.d/site-c.com.conf
方式二:sites-available + sites-enabled(Debian/Ubuntu风格)
# 在sites-available中创建配置
sudo nano /etc/nginx/sites-available/site-a.com
# 创建软链接到sites-enabled启用站点
sudo ln -s /etc/nginx/sites-available/site-a.com /etc/nginx/sites-enabled/
# 禁用站点只需删除软链接
sudo rm /etc/nginx/sites-enabled/site-a.com
站点A - 静态网站:
# /etc/nginx/conf.d/site-a.com.conf
server {
listen 80;
server_name site-a.com www.site-a.com;
root /var/www/site-a.com/html;
index index.html index.htm;
access_log /var/log/nginx/site-a.com/access.log;
error_log /var/log/nginx/site-a.com/error.log;
location / {
try_files $uri $uri/ =404;
}
# 静态资源缓存
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg)$ {
expires 30d;
access_log off;
}
}
站点B - 反向代理Node.js应用:
# /etc/nginx/conf.d/site-b.com.conf
server {
listen 80;
server_name site-b.com www.site-b.com;
access_log /var/log/nginx/site-b.com/access.log;
error_log /var/log/nginx/site-b.com/error.log;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
站点C - PHP站点(WordPress等):
# /etc/nginx/conf.d/site-c.com.conf
server {
listen 80;
server_name site-c.com www.site-c.com;
root /var/www/site-c.com/html;
index index.php index.html;
access_log /var/log/nginx/site-c.com/access.log;
error_log /var/log/nginx/site-c.com/error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
为每个站点单独申请SSL证书并配置HTTPS:
# 使用certbot为所有站点申请证书
sudo certbot --nginx -d site-a.com -d www.site-a.com
sudo certbot --nginx -d site-b.com -d www.site-b.com
sudo certbot --nginx -d site-c.com -d www.site-c.com
Certbot会自动修改每个站点的配置文件,添加SSL相关指令。手动配置HTTPS的示例:
server {
listen 80;
server_name site-a.com www.site-a.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name site-a.com www.site-a.com;
ssl_certificate /etc/letsencrypt/live/site-a.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site-a.com/privkey.pem;
root /var/www/site-a.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
配置默认Server Block处理未匹配的域名或直接IP访问:
# /etc/nginx/conf.d/default.conf
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name _;
# 自签名证书(避免443端口报错)
ssl_certificate /etc/nginx/ssl/default.pem;
ssl_certificate_key /etc/nginx/ssl/default.key;
# 直接返回444(关闭连接)或403
return 444;
}
这样可以防止未备案的域名解析到你的VPS IP后显示其他站点的内容。
多个站点共享的配置可以提取到单独的文件中复用:
# /etc/nginx/snippets/ssl-params.conf
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options nosniff;
# /etc/nginx/snippets/proxy-params.conf
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 在站点配置中引用
server {
listen 443 ssl http2;
server_name site-a.com;
include /etc/nginx/snippets/ssl-params.conf;
location / {
proxy_pass http://127.0.0.1:3000;
include /etc/nginx/snippets/proxy-params.conf;
}
}
# 检查所有配置文件语法
sudo nginx -t
# 重新加载配置(不中断服务)
sudo nginx -s reload
# 查看当前加载的所有Server Block
sudo nginx -T | grep "server_name"
# 测试特定域名的路由
curl -H "Host: site-a.com" http://127.0.0.1/
多站点管理建议:
nginx -t 在重载前检查配置,避免因语法错误导致服务中断Tip: 更多教程请查看新手教程。