Nginx 如何配置虚拟主机?有哪些配置方式?
Nginx 虚拟主机(Virtual Host)允许在同一台服务器上运行多个网站,通过不同的域名、端口或 IP 地址来区分不同的站点。
基于域名的虚拟主机:
nginxserver { listen 80; server_name example.com www.example.com; root /var/www/example.com; index index.html index.php; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; location / { try_files $uri $uri/ =404; } } server { listen 80; server_name test.com www.test.com; root /var/www/test.com; index index.html index.php; access_log /var/log/nginx/test.com.access.log; error_log /var/log/nginx/test.com.error.log; location / { try_files $uri $uri/ =404; } }
基于端口的虚拟主机:
nginxserver { listen 80; server_name example.com; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; } } server { listen 8080; server_name example.com; root /var/www/example.com/admin; index index.html; location / { try_files $uri $uri/ =404; } } server { listen 8443 ssl; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; root /var/www/example.com/secure; index index.html; location / { try_files $uri $uri/ =404; } }
基于 IP 地址的虚拟主机:
nginxserver { listen 192.168.1.100:80; server_name example.com; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; } } server { listen 192.168.1.101:80; server_name example.com; root /var/www/example.com/mirror; index index.html; location / { try_files $uri $uri/ =404; } }
通配符域名:
nginx# 匹配所有子域名 server { listen 80; server_name *.example.com; root /var/www/subdomains; index index.html; location / { # 使用子域名作为目录名 set $subdomain $host; if ($subdomain ~* ^(.*)\.example\.com$) { set $subdomain $1; } root /var/www/subdomains/$subdomain; } } # 匹配所有域名(默认虚拟主机) server { listen 80 default_server; server_name _; root /var/www/default; index index.html; location / { return 404; } }
正则表达式域名:
nginxserver { listen 80; server_name ~^(?<subdomain>.+)\.example\.com$; root /var/www/example.com/$subdomain; index index.html; location / { try_files $uri $uri/ =404; } } server { listen 80; server_name ~^(?<user>.+)\.users\.example\.com$; root /var/www/users/$user; index index.html; location / { try_files $uri $uri/ =404; } }
HTTPS 虚拟主机:
nginxserver { listen 80; server_name example.com; # 重定向到 HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; } }
多域名共享配置:
nginx# 定义共享配置 map $host $root_path { example.com /var/www/example.com; test.com /var/www/test.com; default /var/www/default; } server { listen 80; server_name example.com test.com; root $root_path; index index.html; location / { try_files $uri $uri/ =404; } }
反向代理虚拟主机:
nginxupstream backend1 { server 192.168.1.100:8080; server 192.168.1.101:8080; } upstream backend2 { server 192.168.1.200:8080; server 192.168.1.201:8080; } server { listen 80; server_name api.example.com; location / { proxy_pass http://backend1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } server { listen 80; server_name admin.example.com; location / { proxy_pass http://backend2; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
PHP 虚拟主机:
nginxserver { listen 80; server_name example.com; root /var/www/example.com; index index.php index.html; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } }
静态站点虚拟主机:
nginxserver { listen 80; server_name static.example.com; root /var/www/static; index index.html; # 启用 Gzip 压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript; # 静态资源缓存 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; } location / { try_files $uri $uri/ =404; } }
虚拟主机配置文件分离:
nginx# /etc/nginx/nginx.conf http { include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } # /etc/nginx/sites-available/example.com server { listen 80; server_name example.com; root /var/www/example.com; index index.html; location / { try_files $uri $uri/ =404; } } # 创建符号链接启用站点 # ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
虚拟主机最佳实践:
- 配置文件分离:每个虚拟主机使用独立的配置文件
- 命名规范:使用域名作为配置文件名
- 日志分离:每个虚拟主机使用独立的日志文件
- 默认主机:配置 default_server 处理未知请求
- SSL 配置:所有生产环境使用 HTTPS
- 错误页面:为每个虚拟主机配置自定义错误页面
- 安全头:添加安全相关的 HTTP 头
- 性能优化:启用 Gzip 压缩和缓存
完整虚拟主机配置示例:
nginx# /etc/nginx/sites-available/example.com server { listen 80; server_name example.com www.example.com; # 重定向到 HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name example.com www.example.com; # SSL 配置 ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # 根目录 root /var/www/example.com; index index.php index.html; # 日志 access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; # 安全头 add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; # Gzip 压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript; # 静态资源 location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; } # PHP 处理 location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # 主路由 location / { try_files $uri $uri/ /index.php?$query_string; } # 禁止访问隐藏文件 location ~ /\. { deny all; access_log off; log_not_found off; } }