前言 为什么要做子域名配置
假设一个服务器上在不同端口各存在一个网络服务。例如:域名为 example.com,服务器上 localhost:2236 提供博客服务,localhost:2237提供其它的服务,等等。相较于输入不同的端口,我们可能更倾向于输入子域名来达到访问不同服务的目的。例如 blog.example.com 指向 localhost:2236; other.example.com 指向 localhost:2237。但域名的解析服务不支持直接对端口的解析。
一般来说,实际不同的网络服务会拆分到不同的服务器上,但是由于穷,我也只能用着腾讯云一年108块的廉价服务器搭自己的服务端,那么要怎么把不同的端口配置到我们解析的子域名上呢,了解到Nginx有proxy_pass的功能之后,可以用Nginx来解决这个问题。
配置步骤
1 添加子域名的解析服务
首先要在你的域名解析记录上添加子域名的解析,全部指向你的目标服务器,这里我用的是腾讯云的域名,解析记录设置参考如下图,其中记录值全部填写相同的服务器公网IP地址。

2 配置Nginx
这里我的服务器使用Docker容器来运行Nginx,并且为了SSL证书,使用的是OHTTPS官方的修改版Nginx镜像,不过在配置上和常规Nginx没有区别。
首先我默认你已经用Nginx构建好了自己的一个静态页面,同时配置好了SSL证书,下面的讲解都会在443端口接受HTTPS。
首先找到你的Nginx的配置文件nginx.conf,一般在/etc/nginx目录下,我们主要关注http块下的内容,如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| http { server { listen 443 ssl; server_name blog.madsam.work;
include /etc/nginx/default.d/*.conf;
location / { root /usr/share/nginx/html; index index.html; }
error_page 404 /404.html; location = /404.html { root /usr/share/nginx/html; }
error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
server { listen 443 ssl; server_name api.madsam.work;
location / { proxy_pass http://YOUR_IP_ADDRESS:PORT; proxy_redirect off; proxy_set_header Host $proxy_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 _; rewrite ^(.*)$ https://$host$1 permanent; }
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;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf; }
|
上面的配置文件中,去掉了SSL证书和服务器公网IP相关的部分,我们拿第一个server块来举例,这是一个配置nginx静态页面到子域名的模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| server { listen 443 ssl; server_name blog.madsam.work;
include /etc/nginx/default.d/*.conf;
location / { root /usr/share/nginx/html; index index.html; }
}
|
这里第一个关键配置项是server_name,结合下面的location决定了nginx要在哪个子域名呈现哪个静态页面。
接下来我们再假设有一个SpringBoot服务端接口项目运行在同一个服务器的2222接口,那就是第二个server块的配置模式,利用了nginx的proxy_pass功能。
1 2 3 4 5 6 7 8 9 10 11 12 13
| server { listen 443 ssl; server_name api.madsam.work;
location / { proxy_pass http://YOUR_IP_ADDRESS:PORT; proxy_redirect off; proxy_set_header Host $proxy_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
|
也很简单,还是在server_name项输入相关的子域名,这里在proxy_pass处输入原始的baseURL,例如你有一个login接口为http://44.222.6.111:2222/login
,那么在proxy_pass项中输入http://44.222.6.111:2222
即可。
这里由于使用的是接口服务,意味着请求类型和请求体是不能出问题的,但是nginx在重定向的时候会使用301,也就是说如果访问端错误地从80端口提交请求,那么重定向的过程会导致请求全部变成GET,从而丢失请求体。一个解决方案是在80端口使用rewrite+保持请求状态,如下例。
1 2 3 4 5
| server { listen 80; server_name _; rewrite ^(.*)$ https://$host$1 permanent; }
|
当然也可以多加一个80端口的匹配,再做一次proxy_pass。
完成之后可以重启nginx看是否配置成功。
另外如果你对nginx的proxy_pass配置感兴趣,例如想从nginx端实现错误请求的拦截等,可以看下面的更详细的全面讲解,这里就不多赘述了。
Nginx: Everything about proxy_pass - DEV Community