在现代的Web应用开发中,网站的数量和复杂性越来越高,多个网站使用同一个域名的情况也越来越常见。通过Nginx配置,我们可以轻松实现两个网站共用一个域名,并根据特定的路径、子域名或其他规则对流量进行分发。本文将详细介绍如何使用Nginx配置两个网站共用一个域名的方案。
场景描述
假设我们有一个域名为example.com
,需要通过该域名运行两个网站:
- 一个位于路径
/site1
的Web应用(如一个博客)。 - 另一个位于路径
/site2
的Web应用(如一个电商平台)。
我们希望使用Nginx进行反向代理,将请求分发到不同的网站。
Nginx配置思路
Nginx作为一个高性能的反向代理服务器,具备极高的灵活性。我们可以通过它来实现:
- 基于URI路径的流量分发(通过
location
指令) - 对不同的Web应用进行代理(使用
proxy_pass
)
下面我们将介绍如何编写Nginx配置文件,并详细解析每一行的意义。
Nginx配置示例
nginx
server {
listen 80;
server_name example.com;
location /site1/ {
proxy_pass http://localhost:8081/;
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_set_header X-Forwarded-Proto $scheme;
}
location /site2/ {
proxy_pass http://localhost:8082/;
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_set_header X-Forwarded-Proto $scheme;
}
}
逐行解析配置
-
server {
这是定义一个Nginx服务器块的开始。在这个块内,我们将配置监听端口、域名及相关的处理规则。
-
listen 80;
这行指令告诉Nginx监听80端口,也就是HTTP默认的端口。当用户访问
http://example.com
时,Nginx会处理该请求。如果你希望配置HTTPS,则需要监听443端口,并添加SSL相关配置。 -
server_name example.com;
该指令用于指定虚拟主机的域名。在这个例子中,我们将域名设置为
example.com
,即所有访问example.com
的请求都会进入这个服务器块。 -
location /site1/ {
location
指令用于定义匹配规则。在这里,/site1/
表示匹配URL路径为example.com/site1/
的所有请求。location
块内的配置将处理这些请求。 -
proxy_pass http://localhost:8081/;
这是关键的反向代理配置。
proxy_pass
指令告诉Nginx将匹配的请求转发到http://localhost:8081/
,也就是将/site1/
路径的请求代理给运行在本地8081端口的Web应用。 -
proxy_set_header Host $host;
该指令将客户端请求中的
Host
头转发给后端服务器,$host
是Nginx的内置变量,表示客户端请求中的Host值,即example.com
。这对于后端服务器正确处理请求是非常重要的,尤其在涉及到虚拟主机或跨域问题时。 -
proxy_set_header X-Real-IP $remote_addr;
Nginx在代理请求时,默认不会传递客户端的真实IP。这行指令告诉Nginx将客户端的真实IP(即
$remote_addr
变量)添加到X-Real-IP
头中,以便后端服务器能够知道请求的来源IP。 -
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
X-Forwarded-For
是一个常用的HTTP头,通常用于记录原始客户端的IP地址。如果请求经过了多个代理,Nginx会将当前的客户端IP附加到已有的X-Forwarded-For
头中,从而保留整个代理链。 -
proxy_set_header X-Forwarded-Proto $scheme;
该指令设置
X-Forwarded-Proto
头,用来告诉后端服务器客户端使用的协议是http
还是https
。$scheme
是Nginx的内置变量,它的值为当前请求的协议。 -
location /site2/ {
同样,
location /site2/
块用于匹配路径/site2/
的请求。这些请求会被转发到另外一个Web应用(通过8082端口)。 -
proxy_pass http://localhost:8082/;
将
/site2/
路径的请求代理给本地8082端口的Web应用。
解释两个Web应用的工作流程
假设两个Web应用分别是:
- 一个博客应用,运行在8081端口。
- 一个电商应用,运行在8082端口。
当用户访问http://example.com/site1/
时,Nginx会将请求代理到8081端口,即博客应用。当访问http://example.com/site2/
时,Nginx会将请求代理到8082端口,即电商应用。Nginx只负责代理请求,实际的页面渲染和业务逻辑由后端Web应用负责。
更多的Nginx配置技巧
去掉路径重写
在上面的配置中,注意proxy_pass
后面的URL以斜杠/
结尾。这意味着Nginx会保留请求的路径结构,即/site1/
不会被自动移除。如果你希望在将请求代理给后端应用时移除/site1/
,可以使用如下配置:
nginx
location /site1/ {
rewrite ^/site1/(.*)$ /$1 break;
proxy_pass http://localhost:8081/;
}
rewrite
指令用于重写请求路径。这里的^/site1/(.*)$
表示匹配/site1/
后的所有路径,并通过/$1
保留其后缀路径。
使用子域名代替路径
如果你不希望使用路径来区分两个网站,可以考虑使用子域名。例如,可以为博客应用配置blog.example.com
,为电商应用配置shop.example.com
。
配置如下:
nginx
server {
listen 80;
server_name blog.example.com;
location / {
proxy_pass http://localhost:8081/;
}
}
server {
listen 80;
server_name shop.example.com;
location / {
proxy_pass http://localhost:8082/;
}
}
通过server_name
指令,我们可以为不同的子域名配置不同的服务器块,从而将流量分发到不同的后端应用。
总结
通过Nginx,我们可以非常轻松地将多个Web应用部署在同一个域名下,无论是通过不同的路径,还是通过子域名。本文的示例展示了如何配置两个网站共用一个域名,并详细解释了每个配置项的作用。
在实际的生产环境中,需要考虑更多的细节,比如SSL加密、缓存优化、负载均衡等,这些都是Nginx能够提供的强大功能。