在Nginx配置中,虚拟主机(Virtual Host)允许通过不同的域名或IP地址在同一台服务器上托管多个网站,而针对虚拟主机下的子文件或子目录进行单独配置,通常需要通过location块、alias指令或rewrite规则来实现精细化的请求处理,以下将从配置原理、实践步骤、常见场景及注意事项等方面展开详细说明。
配置原理与核心指令
Nginx的虚拟主机配置基于server块,每个server块通过server_name(域名)或listen(IP+端口)匹配请求,当需要针对虚拟主机下的特定子文件或子目录进行单独配置时,核心在于使用location块定位请求路径,并结合以下指令实现:
-
root vs alias:
- root指令:将请求的根目录指向指定路径,location后的路径会附加到root路径后。
location /images/ { root /data; }
实际映射到/data/images/
。 - alias指令:直接替换location匹配的路径为指定路径。
location /images/ { alias /data/static/; }
实际映射到/data/static/
,注意alias后的路径需以结尾,且location路径需精确匹配。
- root指令:将请求的根目录指向指定路径,location后的路径会附加到root路径后。
-
try_files:用于按顺序检查文件或目录是否存在,不存在则返回404或转发到其他location。
try_files $uri $uri/ /index.php?$query_string;
可确保静态文件优先被直接访问,动态请求转发到PHP处理。 -
rewrite:通过正则表达式重写URL,常用于伪静态或路径转发。
rewrite ^/old/(.*)$ /new/$1 permanent;
将旧路径永久重定向到新路径。
实践步骤与示例
假设需要为域名example.com
下的/docs/
子目录配置独立的文档服务,同时/api/
路径请求转发到后端应用,具体步骤如下:
基础虚拟主机配置
首先在Nginx配置文件(如/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; # 其他全局配置... }
子目录独立配置
场景1:/docs/
指向独立目录
若/docs/
下的文件存放在/var/www/docs
,需使用alias指令(注意location需以结尾):
location /docs/ { alias /var/www/docs/; try_files $uri $uri/ =404; autoindex on; # 可选,开启目录列表 }
场景2:/api/
转发到后端服务
若/api/
请求需代理到Node.js应用(运行在localhost:3000):
location /api/ { proxy_pass http://localhost:3000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
场景3:子文件特定处理
若需对/download/
目录下的文件进行限速或认证:
location /download/ { alias /var/www/download/; limit_rate 100k; # 限速100KB/s auth_basic "Restricted"; # 基本认证 auth_basic_user_file /etc/nginx/.htpasswd; }
多域名子目录配置
若需为子域名sub.example.com
的/static/
路径配置独立资源:
server { listen 80; server_name sub.example.com; root /var/www/sub; location /static/ { alias /var/www/static/; expires 7d; # 缓存7天 } }
常见问题与注意事项
- 路径匹配优先级:location的匹配顺序为:精确匹配 > 前缀匹配 > 正则匹配。
location /docs/api/
优先于location /docs/
,需避免规则冲突。 - root与alias混用陷阱:在同一个location块中避免同时使用root和alias,且alias后的路径不能包含匹配的location路径部分。
- 软链接与权限:若子目录使用alias,需确保目标路径存在且Nginx进程有读取权限,软链接可能需要
disable_symlinks off;
支持。 - 日志分离:可通过
access_log /var/log/nginx/docs.log;
为子目录配置独立日志,便于排查问题。
配置效果对比表
配置场景 | 指令组合 | 示例路径 | 实际映射路径 | 用途 |
---|---|---|---|---|
子目录独立 | location + alias | /docs/ → /var/www/docs/ |
/var/www/docs/index.html |
隔离资源目录 |
动态请求转发 | location + proxy_pass | /api/ → http://localhost:3000/ |
http://localhost:3000/api/ |
后端服务代理 |
静态文件缓存 | location + expires | /static/ + 7d |
浏览器缓存7天 | 性能优化 |
文件访问控制 | location + auth_basic | /admin/ + 认证 |
需验证用户密码 | 安全限制 |
相关问答FAQs
Q1:为什么使用alias时location路径必须以结尾?
A1:Nginx的alias指令会直接替换location匹配的路径,若location为/docs
(无),请求/docs/file.txt
会被替换为/var/www/docsfile.txt
(路径错误);而/docs/
会正确匹配为/var/www/docs/file.txt
,alias要求location路径以结尾,确保路径拼接正确。
Q2:如何将子目录的请求重定向到另一个域名?
A2:可通过rewrite或return指令实现,将example.com/old/
永久重定向到newdomain.com/new/
:
location /old/ { rewrite ^/old/(.*)$ http://newdomain.com/new/$1 permanent; }
或使用return指令(更简洁):
location /old/ { return 301 http://newdomain.com/new$request_uri; }
其中permanent
或301
表示永久重定向,$request_uri
保留原始查询参数。