美国服务器Nginx虚拟主机配置:在一台服务器上托管多个网站
在当今的Web托管环境中,最大化美国服务器资源利用率是每个运维人员的重要目标。Nginx虚拟主机(Server Blocks)技术允许我们在单台服务器上运行多个独立的网站,每个网站都可以拥有自己的域名、内容和配置,而用户访问时完全感受不到这些网站共享同一台服务器。
一、虚拟主机核心概念与工作原理
虚拟主机技术优势:
成本效益:大幅降低硬件和运维成本
资源优化:充分利用服务器计算和带宽资源
管理简便:集中管理多个网站,维护更高效
灵活扩展:轻松添加新网站,无需额外硬件投入
Nginx虚拟主机类型:
基于域名:通过不同域名区分网站(最常用)
基于IP地址:通过不同IP地址区分网站
基于端口:通过不同端口号区分网站
工作原理:
当用户发起HTTP请求时,Nginx会检查请求头中的Host字段,然后匹配对应的server块配置,将请求路由到正确的网站根目录。这个过程对用户完全透明,每个网站都像是运行在独立的服务器上。
二、环境准备与基础配置
系统要求检查:
bash
# 检查Nginx是否安装nginx -v# 查看Nginx配置文件目录结构ls -la /etc/nginx/# 检查Nginx服务状态sudo systemctl status nginx
安装Nginx(如未安装):
Ubuntu/Debian:
bash
sudo apt updatesudo apt install nginxsudo systemctl enable nginxsudo systemctl start nginx
CentOS/RHEL:
bash
sudo yum install epel-releasesudo yum install nginxsudo systemctl enable nginxsudo systemctl start nginx
创建网站目录结构:
bash
# 创建主要网站目录sudo mkdir -p /var/www/example.com/{public_html,logs,backup}sudo mkdir -p /var/www/test.com/{public_html,logs,backup}sudo mkdir -p /var/www/demo.com/{public_html,logs,backup}# 设置正确的所有权和权限sudo chown -R www-data:www-data /var/www/ # Ubuntu/Debiansudo chown -R nginx:nginx /var/www/ # CentOS/RHELsudo chmod -R 755 /var/www/# 创建测试页面echo "<h1>Welcome to Example.com</h1><p>这是主网站</p>" | sudo tee /var/www/example.com/public_html/index.htmlecho "<h1>Welcome to Test.com</h1><p>测试网站内容</p>" | sudo tee /var/www/test.com/public_html/index.htmlecho "<h1>Welcome to Demo.com</h1><p>演示网站内容</p>" | sudo tee /var/www/demo.com/public_html/index.html三、基于域名的虚拟主机配置
这是最常见的虚拟主机配置方式,通过不同的域名来访问不同的网站。
创建虚拟主机配置文件:
示例主站配置 (
example.com.conf):
bash
sudo nano /etc/nginx/sites-available/example.com.conf
配置内容:
nginx
server {
# 监听端口和域名配置
listen 80;
listen [::]:80;
# 主域名
server_name example.com;
# 别名域名(可选)
server_name www.example.com;
# 网站根目录
root /var/www/example.com/public_html;
# 默认索引文件
index index.html index.htm index.php;
# 访问日志配置
access_log /var/www/example.com/logs/access.log;
error_log /var/www/example.com/logs/error.log;
# 主位置块配置
location / {
# 尝试提供请求的文件,如果不存在则返回404
try_files $uri $uri/ =404;
}
# PHP处理配置(如使用PHP)
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 静态资源缓存配置
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Vary "Accept-Encoding";
}
# 安全设置 - 隐藏敏感文件
location ~ /\.(ht|git|svn) {
deny all;
access_log off;
log_not_found off;
}
# 防止直接访问某些文件类型
location ~* \.(log|sql|tar|gz)$ {
deny all;
}
# 自定义错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
# 文件上传大小限制
client_max_body_size 100M;}测试站点配置 (
test.com.conf):
bash
sudo nano /etc/nginx/sites-available/test.com.conf
配置内容:
nginx
server {
listen 80;
server_name test.com www.test.com;
root /var/www/test.com/public_html;
index index.html index.htm;
access_log /var/www/test.com/logs/access.log;
error_log /var/www/test.com/logs/error.log;
location / {
try_files $uri $uri/ =404;
}
# 特定于测试站点的配置
location /api/ {
# API接口特殊处理
try_files $uri $uri/ /index.html;
}
# 开发环境特殊设置
location ~ /\.env {
deny all;
access_log off;
log_not_found off;
}}演示站点配置 (
demo.com.conf):
bash
sudo nano /etc/nginx/sites-available/demo.com.conf
配置内容:
nginx
server {
listen 80;
server_name demo.com www.demo.com;
root /var/www/demo.com/public_html;
index index.html index.htm;
# 不同的日志格式
log_format demo_format '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time"';
access_log /var/www/demo.com/logs/access.log demo_format;
error_log /var/www/demo.com/logs/error.log;
location / {
try_files $uri $uri/ /index.html;
}
# 演示站点特殊目录
location /downloads/ {
# 允许目录列表
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
# 下载文件类型设置
add_header Content-Disposition "attachment";
}}启用虚拟主机站点:
bash
# 创建符号链接到sites-enabled目录sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/sudo ln -s /etc/nginx/sites-available/test.com.conf /etc/nginx/sites-enabled/sudo ln -s /etc/nginx/sites-available/demo.com.conf /etc/nginx/sites-enabled/# 检查配置语法sudo nginx -t# 重新加载Nginx配置sudo systemctl reload nginx
四、基于端口的虚拟主机配置
当需要通过不同端口访问不同网站时,基于端口的配置非常有用,特别适用于开发测试环境。
配置额外监听端口:
bash
# 在nginx.conf的http块中确保包含以下内容sudo nano /etc/nginx/nginx.conf
创建基于端口的虚拟主机:
端口8080配置 (
dev-site-8080.conf):
bash
sudo nano /etc/nginx/sites-available/dev-site-8080.conf
nginx
server {
# 监听8080端口
listen 8080;
listen [::]:8080;
server_name _; # 匹配所有域名
root /var/www/dev-site/public_html;
index index.html index.htm;
# 开发环境特殊配置
access_log /var/www/dev-site/logs/access-8080.log;
error_log /var/www/dev-site/logs/error-8080.log;
location / {
try_files $uri $uri/ =404;
}
# 开发环境允许显示错误详情
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_param PHP_VALUE "display_errors=On";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# 开发环境不缓存
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";}端口8081配置 (
staging-site-8081.conf):
bash
sudo nano /etc/nginx/sites-available/staging-site-8081.conf
nginx
server {
listen 8081;
listen [::]:8081;
server_name staging.example.com;
root /var/www/staging-site/public_html;
index index.html index.htm;
access_log /var/www/staging-site/logs/access-8081.log;
error_log /var/www/staging-site/logs/error-8081.log;
location / {
try_files $uri $uri/ =404;
}
# 预发布环境配置
location /api/ {
# 指向测试API端点
proxy_pass http://test-api.internal:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}}启用端口虚拟主机:
bash
sudo ln -s /etc/nginx/sites-available/dev-site-8080.conf /etc/nginx/sites-enabled/sudo ln -s /etc/nginx/sites-available/staging-site-8081.conf /etc/nginx/sites-enabled/# 检查防火墙设置(如果需要)sudo ufw allow 8080/tcpsudo ufw allow 8081/tcpsudo nginx -tsudo systemctl reload nginx
五、默认虚拟主机与通配符配置
配置默认虚拟主机:
当请求的域名不匹配任何已配置的server_name时,使用默认虚拟主机。
bash
sudo nano /etc/nginx/sites-available/default.conf
nginx
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# 返回404或重定向到主站
return 404;
# 或者重定向:return 301 https://example.com$request_uri;
# 可选:显示自定义默认页面
# root /var/www/default;
# index index.html;
# location / {
# try_files $uri $uri/ =404;
# }
access_log /var/log/nginx/default_access.log;
error_log /var/log/nginx/default_error.log;}通配符子域名配置:
bash
sudo nano /etc/nginx/sites-available/wildcard.conf
nginx
server {
listen 80;
# 匹配所有子域名
server_name ~^(?<subdomain>.+)\.example\.com$;
# 根据子域名动态设置根目录
root /var/www/example.com/subdomains/$subdomain/public_html;
index index.html index.htm;
access_log /var/www/example.com/subdomains/$subdomain/logs/access.log;
error_log /var/www/example.com/subdomains/$subdomain/logs/error.log;
location / {
try_files $uri $uri/ =404;
}
# 如果子域名目录不存在,返回404
if (!-d /var/www/example.com/subdomains/$subdomain) {
return 404;
}}六、SSL/TLS安全配置
为虚拟主机启用HTTPS加密:
基础SSL配置:
nginx
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
# SSL证书路径
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# SSL安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# SSL会话设置
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 安全头设置
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
root /var/www/example.com/public_html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}}# HTTP重定向到HTTPSserver {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;}使用Let's Encrypt免费SSL:
bash
# 安装Certbotsudo apt install certbot python3-certbot-nginx# 为虚拟主机获取SSL证书sudo certbot --nginx -d example.com -d www.example.com# 自动续期测试sudo certbot renew --dry-run
七、高级虚拟主机配置技巧
1. 条件配置基于环境变量:
nginx
# 在主配置文件中设置env APPLICATION_ENV;server {
listen 80;
server_name example.com;
root /var/www/example.com/public_html;
# 根据环境变量加载不同配置
include /etc/nginx/conf.d/${APPLICATION_ENV}-config.conf;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}}2. 负载均衡后端配置:
nginx
upstream backend_servers {
server 192.168.1.101:8000 weight=3;
server 192.168.1.102:8000 weight=2;
server 192.168.1.103:8000 weight=1;}server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend_servers;
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_next_upstream error timeout invalid_header http_500 http_502 http_503;
}}3. 多语言网站配置:
nginx
server {
listen 80;
server_name multilingual.com;
root /var/www/multilingual.com/public_html;
# 根据浏览器语言重定向
location / {
if ($http_accept_language ~* "^zh") {
return 301 /zh$request_uri;
}
if ($http_accept_language ~* "^en") {
return 301 /en$request_uri;
}
# 默认语言
return 301 /en$request_uri;
}
# 中文版本
location /zh/ {
alias /var/www/multilingual.com/public_html/zh/;
index index.html;
try_files $uri $uri/ /zh/index.html;
}
# 英文版本
location /en/ {
alias /var/www/multilingual.com/public_html/en/;
index index.html;
try_files $uri $uri/ /en/index.html;
}}八、性能优化配置
1. 静态资源优化:
nginx
server {
listen 80;
server_name example.com;
root /var/www/example.com/public_html;
# Gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml image/svg+xml;
location ~* \.(jpg|jpeg|png|gif|ico|webp)$ {
expires 1y;
add_header Cache-Control "public, immutable";
# WebP格式优先
add_header Vary "Accept";
}
location ~* \.(css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location ~* \.(woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Access-Control-Allow-Origin "*";
}}2. 安全加固配置:
nginx
server {
listen 80;
server_name example.com;
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# 隐藏Nginx版本信息
server_tokens off;
# 限制请求方法
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 405;
}
# 限制请求体大小
client_max_body_size 10M;
# 限制缓冲区大小,防止缓冲区溢出攻击
client_body_buffer_size 128k;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;}九、监控与日志分析
配置详细访问日志:
nginx
# 自定义日志格式log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" '
'uht="$upstream_header_time" urt="$upstream_response_time"';server {
listen 80;
server_name example.com;
access_log /var/www/example.com/logs/access.log detailed;
error_log /var/www/example.com/logs/error.log warn;
# 实时状态页面(仅限内网访问)
location /nginx_status {
stub_status on;
access_log off;
allow 192.168.1.0/24;
allow 127.0.0.1;
deny all;
}}日志分析脚本示例:
bash
#!/bin/bash# nginx-log-analyzer.shLOG_FILE="/var/www/example.com/logs/access.log"echo "=== Nginx虚拟主机访问统计 ==="echo "分析文件: $LOG_FILE"echo "统计时间: $(date)"echo ""# 总请求数total_requests=$(wc -l < "$LOG_FILE")echo "1. 总请求数: $total_requests"# 最频繁的访问IPecho -e "\n2. 最频繁访问IP:"awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10# 最受欢迎的页面echo -e "\n3. 最受欢迎页面:"awk '{print $7}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10# 响应状态码统计echo -e "\n4. HTTP状态码分布:"awk '{print $9}' "$LOG_FILE" | sort | uniq -c | sort -nr# 用户代理统计echo -e "\n5. 主要用户代理:"awk -F\" '{print $6}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10十、故障排查与维护
配置验证与测试:
bash
# 检查Nginx配置语法sudo nginx -t# 检查虚拟主机配置sudo nginx -T | grep -A 20 "server_name"# 测试虚拟主机响应curl -H "Host: example.com" http://服务器IPcurl -H "Host: test.com" http://服务器IP# 检查端口监听sudo netstat -tulpn | grep nginx# 查看错误日志sudo tail -f /var/log/nginx/error.log
常见问题解决方案:
权限问题:
bash
# 修复文件和目录权限sudo chown -R www-data:www-data /var/www/sudo find /var/www/ -type d -exec chmod 755 {} \;sudo find /var/www/ -type f -exec chmod 644 {} \;日志文件问题:
bash
# 创建日志目录并设置权限sudo mkdir -p /var/www/example.com/logssudo touch /var/www/example.com/logs/{access,error}.logsudo chown www-data:www-data /var/www/example.com/logs/*.logsudo chmod 644 /var/www/example.com/logs/*.log配置重载问题:
bash
# 强制停止并重新启动sudo systemctl stop nginxsudo systemctl start nginx# 或者使用信号重载sudo kill -HUP $(cat /var/run/nginx.pid)
十一、自动化部署脚本
虚拟主机创建脚本:
bash
#!/bin/bash# create-vhost.shDOMAIN=$1DOCUMENT_ROOT="/var/www/$DOMAIN/public_html"# 验证输入if [ -z "$DOMAIN" ]; then
echo "用法: $0 域名"
exit 1fi# 创建目录结构sudo mkdir -p "$DOCUMENT_ROOT"sudo mkdir -p "/var/www/$DOMAIN/"{logs,backup}# 设置权限sudo chown -R www-data:www-data "/var/www/$DOMAIN"sudo chmod -R 755 "/var/www/$DOMAIN"# 创建默认页面sudo tee "$DOCUMENT_ROOT/index.html" > /dev/null <<EOF
<html>
<head>
<title>欢迎来到 $DOMAIN</title>
</head>
<body>
<h1>欢迎!</h1>
<p>网站 $DOMAIN 已成功创建。</p>
<p>服务器: $(hostname)</p>
<p>时间: $(date)</p>
</body>
</html>
EOF# 创建Nginx配置文件sudo tee "/etc/nginx/sites-available/$DOMAIN.conf" > /dev/null <<EOF
server {
listen 80;
server_name $DOMAIN www.$DOMAIN;
root $DOCUMENT_ROOT;
index index.html index.htm;
access_log /var/www/$DOMAIN/logs/access.log;
error_log /var/www/$DOMAIN/logs/error.log;
location / {
try_files \$uri \$uri/ =404;
}
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
EOF# 启用站点sudo ln -sf "/etc/nginx/sites-available/$DOMAIN.conf" "/etc/nginx/sites-enabled/"# 测试并重载配置sudo nginx -t && sudo systemctl reload nginxecho "虚拟主机 $DOMAIN 创建完成!"echo "文档根目录: $DOCUMENT_ROOT"echo "配置文件: /etc/nginx/sites-available/$DOMAIN.conf"总结
通过Nginx虚拟主机配置,我们可以高效地在单台服务器上托管多个网站,每个网站都拥有独立的配置和内容。关键成功要素包括:
规划先行:设计清晰的目录结构和命名规范
安全为重:实施适当的安全措施和权限控制
性能优化:配置缓存、压缩和资源优化
监控持续:建立完善的日志记录和监控机制
维护定期:定期检查配置、更新证书、清理日志
最佳实践建议:
使用有意义的配置文件名
为每个虚拟主机创建独立的日志文件
实施定期的备份策略
使用版本控制管理配置文件
建立标准化的部署流程
掌握Nginx虚拟主机技术,不仅能够显著降低服务器成本,还能提高运维效率,为业务扩展提供坚实的技术基础。随着经验的积累,你可以进一步探索更高级的配置技巧,如动态虚拟主机、边缘计算集成等前沿技术。


扫码关注
微信好友
关注抖音