广告位

美国服务器Nginx虚拟主机配置:在一台服务器上托管多个网站

频道: 日期: 浏览:34

在当今的Web托管环境中,最大化美国服务器资源利用率是每个运维人员的重要目标。Nginx虚拟主机(Server Blocks)技术允许我们在单台服务器上运行多个独立的网站,每个网站都可以拥有自己的域名、内容和配置,而用户访问时完全感受不到这些网站共享同一台服务器。

一、虚拟主机核心概念与工作原理

虚拟主机技术优势:

  • 成本效益:大幅降低硬件和运维成本

  • 资源优化:充分利用服务器计算和带宽资源

  • 管理简便:集中管理多个网站,维护更高效

  • 灵活扩展:轻松添加新网站,无需额外硬件投入

Nginx虚拟主机类型:

  1. 基于域名:通过不同域名区分网站(最常用)

  2. 基于IP地址:通过不同IP地址区分网站

  3. 基于端口:通过不同端口号区分网站

工作原理:
当用户发起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

三、基于域名的虚拟主机配置

这是最常见的虚拟主机配置方式,通过不同的域名来访问不同的网站。

创建虚拟主机配置文件:

  1. 示例主站配置 (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;}

  1. 测试站点配置 (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;
    }}

  1. 演示站点配置 (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

创建基于端口的虚拟主机:

  1. 端口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";}

  1. 端口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

常见问题解决方案:

  1. 权限问题

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 {} \;

  1. 日志文件问题

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

  1. 配置重载问题

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虚拟主机配置,我们可以高效地在单台服务器上托管多个网站,每个网站都拥有独立的配置和内容。关键成功要素包括:

  1. 规划先行:设计清晰的目录结构和命名规范

  2. 安全为重:实施适当的安全措施和权限控制

  3. 性能优化:配置缓存、压缩和资源优化

  4. 监控持续:建立完善的日志记录和监控机制

  5. 维护定期:定期检查配置、更新证书、清理日志

最佳实践建议:

  • 使用有意义的配置文件名

  • 为每个虚拟主机创建独立的日志文件

  • 实施定期的备份策略

  • 使用版本控制管理配置文件

  • 建立标准化的部署流程

掌握Nginx虚拟主机技术,不仅能够显著降低服务器成本,还能提高运维效率,为业务扩展提供坚实的技术基础。随着经验的积累,你可以进一步探索更高级的配置技巧,如动态虚拟主机、边缘计算集成等前沿技术。

生成文章图片 (35).jpg

关键词: