广告位

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

频道: 日期: 浏览:67

在当今的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 "
2. 最频繁访问IP:"awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10# 最受欢迎的页面echo -e "
3. 最受欢迎页面:"awk '{print $7}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10# 响应状态码统计echo -e "
4. HTTP状态码分布:"awk '{print $9}' "$LOG_FILE" | sort | uniq -c | sort -nr# 用户代理统计echo -e "
5. 主要用户代理:"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

关键词: