Nginx 虚拟主机配置
Nginx 虚拟主机(Server Block)配置详解
📋 目录
虚拟主机基础
什么是虚拟主机
虚拟主机允许在同一台服务器上运行多个网站,共享服务器资源。
服务器 IP: 192.168.1.100
├─ 网站 1: www.example1.com
├─ 网站 2: www.example2.com
└─ 网站 3: www.example3.com
Nginx 虚拟主机类型
- 基于域名的虚拟主机 - 最常用的方式
- 基于端口的虚拟主机 - 不同端口
- 基于 IP 的虚拟主机 - 不同 IP 地址
基于域名的虚拟主机
基本配置
# 虚拟主机 1
server {
listen 80;
server_name www.example1.com example1.com;
root /var/www/example1;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
# 虚拟主机 2
server {
listen 80;
server_name www.example2.com example2.com;
root /var/www/example2;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}通配符域名
# 匹配所有子域名
server {
listen 80;
server_name *.example.com;
root /var/www/example;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# 匹配所有以 example 开头的域名
server {
listen 80;
server_name example.*;
# ...
}正则表达式域名
# 使用正则匹配域名
server {
listen 80;
server_name ~^www\.example\.com$;
# ...
}
# 捕获域名部分
server {
listen 80;
server_name ~^(www\.)?(?<domain>.+)$;
root /var/www/$domain;
index index.html;
}多域名共享配置
server {
listen 80;
server_name example1.com www.example1.com
example2.com www.example2.com
example3.com www.example3.com;
root /var/www/shared;
index index.html;
}基于端口的虚拟主机
不同端口不同网站
# HTTP 网站
server {
listen 80;
server_name example.com;
root /var/www/http;
index index.html;
}
# HTTPS 网站
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
root /var/www/https;
index index.html;
}
# 管理后台
server {
listen 8080;
server_name example.com;
root /var/www/admin;
index index.html;
# 访问控制
allow 192.168.1.0/24;
deny all;
}同一域名不同端口
# 网站端口
server {
listen 80;
listen 8080;
server_name example.com;
root /var/www/website;
index index.html;
}
# API 端口
server {
listen 9000;
server_name example.com;
root /var/www/api;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}基于 IP 的虚拟主机
不同 IP 不同网站
# 监听所有 IP 的 80 端口
server {
listen 80;
server_name example.com;
root /var/www/example;
index index.html;
}
# 监听特定 IP 的 80 端口
server {
listen 192.168.1.100:80;
server_name example.com;
root /var/www/example-ip1;
index index.html;
}
# 监听另一个 IP 的 80 端口
server {
listen 192.168.1.101:80;
server_name example.com;
root /var/www/example-ip2;
index index.html;
}IPv6 虚拟主机
server {
listen 80;
listen [::]:80 ipv6only=on; # IPv6
server_name example.com;
root /var/www/example;
index index.html;
}默认虚拟主机
配置默认虚拟主机
# 默认虚拟主机(捕获所有未匹配的域名)
server {
listen 80 default_server; # default_server 标记
listen [::]:80 default_server;
server_name _; # 无效的域名,表示匹配所有
root /var/www/default;
index index.html;
return 404; # 或者重定向到主页
}拒绝未匹配的域名
# 默认虚拟主机 - 拒绝访问
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# 返回 444(Nginx 特殊状态码,立即关闭连接)
return 444;
}
# 或者返回 404
server {
listen 80 default_server;
server_name _;
return 404;
}
# 或者重定向到主站
server {
listen 80 default_server;
server_name _;
return 301 http://www.example.com$request_uri;
}虚拟主机最佳实践
分离配置文件
# 创建目录结构
/etc/nginx/
├── nginx.conf # 主配置文件
├── sites-available/ # 可用站点配置
│ ├── example1.com
│ ├── example2.com
│ └── default
└── sites-enabled/ # 启用站点配置
├── example1.com -> ../sites-available/example1.com
└── example2.com -> ../sites-available/example2.comInclude 方式
# nginx.conf
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# 基础配置
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# 虚拟主机配置
include /etc/nginx/sites-enabled/*;
}示例站点配置
# /etc/nginx/sites-available/example.com
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.htm;
# 访问日志
access_log /var/log/nginx/example.com.access.log main;
error_log /var/log/nginx/example.com.error.log warn;
# 字符编码
charset utf-8;
# Gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript;
location / {
try_files $uri $uri/ =404;
}
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# 错误页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
# 启用站点
# sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/HTTPS 虚拟主机
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name example.com www.example.com;
# 重定向到 HTTPS
return 301 https://$server_name$request_uri;
}
# HTTPS 虚拟主机
server {
listen 443 ssl http2;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
# 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-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
# SSL 会话缓存
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
try_files $uri $uri/ =404;
}
}泛域名配置
# 泛域名虚拟主机
server {
listen 80;
server_name *.example.com;
# 提取子域名
if ($host ~* ^(.+)\.example\.com$) {
set $subdomain $1;
}
root /var/www/$subdomain;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# 或者使用正则
server {
listen 80;
server_name ~^(?<subdomain>.+)\.example\.com$;
root /var/www/$subdomain;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}多域名共享配置
# 共享配置的虚拟主机
server {
listen 80;
server_name
example1.com www.example1.com
example2.com www.example2.com
example3.com www.example3.com;
root /var/www/shared;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}开发环境虚拟主机
# 开发环境配置
server {
listen 80;
server_name dev.example.com;
root /var/www/dev;
index index.html;
# 开发环境配置
error_log /var/log/nginx/dev.error.log debug;
access_log /var/log/nginx/dev.access.log;
# 禁用缓存
add_header Cache-Control "no-cache, no-store, must-revalidate";
add_header Pragma "no-cache";
add_header Expires "0";
location / {
try_files $uri $uri/ =404;
}
# API 代理到开发服务器
location /api/ {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# WebSocket 代理
location /ws/ {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}🔧 高级技巧
动态虚拟主机
# 根据域名自动选择目录
server {
listen 80;
server_name ~^(www\.)?(?<domain>.+)$;
root /var/www/$domain;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}虚拟主机模板
# 使用 map 配置不同参数
map $host $root_path {
default /var/www/default;
example1.com /var/www/example1;
example2.com /var/www/example2;
~*\.example\.com /var/www/example;
}
server {
listen 80;
server_name _;
root $root_path;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}流量分发
# 根据来源分配不同后端
map $http_referer $backend {
default backend_main;
~*google\.com backend_google;
~*baidu\.com backend_baidu;
~*wechat backend_wechat;
}
upstream backend_main { server 127.0.0.1:8000; }
upstream backend_google { server 127.0.0.1:8001; }
upstream backend_baidu { server 127.0.0.1:8002; }
upstream backend_wechat { server 127.0.0.1:8003; }
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://$backend;
}
}