基于域名、IP、端口的虚拟主机
虚拟主机(Virtual Host)技术允许在一台物理服务器上运行多个网站。Nginx通过server块来实现虚拟主机,可以根据域名、IP地址或端口来区分不同的网站。
这是最常用的虚拟主机配置方式,通过server_name指令匹配不同的域名。
server {
listen 80;
server_name www.example.com;
root /var/www/example;
index index.html index.htm;
access_log /var/log/nginx/example.access.log;
error_log /var/log/nginx/example.error.log;
location / {
try_files $uri $uri/ =404;
}
}
server {
listen 80;
# 多个域名指向同一个网站
server_name www.example.com example.com www.example.net;
root /var/www/example;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
# 匹配所有子域名
server {
listen 80;
server_name *.example.com;
root /var/www/subdomains/$host;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# 匹配特定前缀的域名
server {
listen 80;
server_name ~^(www\.)?(.+)$;
root /var/www/$2;
location / {
try_files $uri $uri/ =404;
}
}
# 主站 - www.example.com
server {
listen 80;
server_name www.example.com example.com;
root /var/www/example;
index index.html index.htm;
access_log /var/log/nginx/example.access.log;
error_log /var/log/nginx/example.error.log;
location / {
try_files $uri $uri/ /index.html;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 7d;
}
}
# 博客站 - blog.example.com
server {
listen 80;
server_name blog.example.com;
root /var/www/blog;
index index.php index.html;
access_log /var/log/nginx/blog.access.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
# API服务 - api.example.com
server {
listen 80;
server_name api.example.com;
access_log /var/log/nginx/api.access.log;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
当服务器有多个IP地址时,可以配置基于IP的虚拟主机。
# 第一个IP的网站
server {
listen 192.168.1.100:80;
server_name www.site1.com;
root /var/www/site1;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# 第二个IP的网站
server {
listen 192.168.1.101:80;
server_name www.site2.com;
root /var/www/site2;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# 监听所有IP
server {
listen 0.0.0.0:80;
server_name www.site3.com;
root /var/www/site3;
index index.html;
}
通过不同的端口区分不同的网站。
# 80端口 - 主站
server {
listen 80;
server_name example.com;
root /var/www/main;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# 8080端口 - 管理后台
server {
listen 8080;
server_name example.com;
root /var/www/admin;
index index.html;
# 限制访问IP
allow 192.168.1.0/24;
deny all;
location / {
try_files $uri $uri/ =404;
}
}
# 8081端口 - 测试环境
server {
listen 8081;
server_name example.com;
root /var/www/test;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
配置默认虚拟主机来处理未匹配的请求。
# 默认虚拟主机(处理所有未匹配的请求)
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# 返回444状态码(关闭连接)
return 444;
}
# 或者返回自定义页面
server {
listen 80 default_server;
server_name _;
root /var/www/default;
location / {
return 403 "Access Denied";
}
}
# 将不带www的域名重定向到带www的域名
server {
listen 80;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
# 主站配置
server {
listen 80;
server_name www.example.com;
root /var/www/example;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# 旧域名重定向到新域名
server {
listen 80;
server_name old-domain.com www.old-domain.com;
return 301 https://new-domain.com$request_uri;
}
Nginx按照以下优先级匹配server_name:
server_name www.example.com;server_name *.example.com;server_name www.example.*;server_name ~^www\.example\.com$;# 优先级1:精确匹配
server {
listen 80;
server_name www.example.com;
return 200 "精确匹配";
}
# 优先级2:前缀通配符
server {
listen 80;
server_name *.example.com;
return 200 "前缀通配符匹配";
}
# 优先级3:后缀通配符
server {
listen 80;
server_name www.example.*;
return 200 "后缀通配符匹配";
}
# 优先级4:正则表达式
server {
listen 80;
server_name ~^www\d+\.example\.com$;
return 200 "正则表达式匹配";
}
# 优先级5:默认server
server {
listen 80 default_server;
server_name _;
return 200 "默认server";
}
# /etc/nginx/conf.d/example.com.conf
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
root /var/www/example/public;
index index.php index.html;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
access_log /var/log/nginx/example.access.log;
error_log /var/log/nginx/example.error.log;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}
虚拟主机是Nginx的核心功能之一,通过合理配置可以在一台服务器上托管多个网站。掌握基于域名、IP和端口的虚拟主机配置方法,以及server_name的匹配规则,是进行Web服务器管理的基础技能。