前言
当一个开发者有了一台云服务器,可能会想着部署一个博客网页,一个工具网站;
也可能是想部署一个网站所以入手了一台云服务器。
Anyway,当需要部署并暴露某个网站时,那它一定需要一个容易被人记住的名字:域名
。
没人会愿意通过ip加端口号的方式去访问一个网站,包括开发者自己。
仅仅有个域名还不够,还需要https的安全证书🔐
。那到底该如何去优雅地暴露服务呢?
我的选择是 「Nginx」 + 「Let's Encrypt」
前者提供域名映射,后者提供安全证书
多域名
当拥有了一个根域名后,就可以扩展出多个子域名了;当然,如果有多个域名更好。
我有一个根域名 tunan.fun
,我就可以拥有多个子域名。i.e. tools.tunan.fun
。
这些都可以在你的域名购买的厂商那里去设置,然后将域名解析到自己的服务器IP上。
如果服务器是中国国内的,那么还需要进行备案,需要几个工作日等待审核处理。
映射到多服务
现在假设我有这样一个需求,我的服务器中部署了两个网站,我想通过不同的域名来访问:
tunan.fun
访问我的博客应用tunan-blog-app
tools.tunan.fun
访问我的工具箱应用tunan-tools-app
该如何使用「Nginx」做映射?
「Nginx」的下载和安装就不在此展开了,主要讲讲如何通过它实现我们的目的。
比如我现在要映射到我的两个服务的前端(两个网站均采用前后端分离的架构)。
tunan-blog-app
基于reac+node.js
框架,通过暴露某个端口(i.e.8080
)作为服务入口。tunan-tools-app
基于vue
框架,利用生成的静态文件dist
做服务入口。
也就是说我需要nginx来帮我做到:
- 当解析到该服务器ip的域名是
tunan.fun
时,nginx帮我把请求映射到localhost:8080
端口的服务上; - 当解析到该服务器ip的域名是
tools.tunan.fun
时,nginx帮我把请求映射到相应的静态文件的index.html
上。
接下来就看看如何编写该配置文件。
配置文件 nginx.conf
找到「Nginx」所在的安装位置中的配置文件nginx.conf
。
可以通过以下两种方式寻找配置文件:
ps -ef | grep nginx
nginx-t
一般情况下,安装目录为
/etc/nginx
找到后修改该配置文件,修改或者新增http{}
中server{}
的配置。
http {
server {
server_name tools.tunan.fun;
root /home/yaodao/my-app/my-tools/front/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
server {
server_name tunan.fun www.tunan.fun;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
通过service nginx reload
命令使新的配置文件生效。
注意这里有
tunan.fun
, 和www.tunan.fun
,这是希望其他人通过这两个域名都能访问到我的博客,它们俩在服务商的域名解析的配置中是不同的两个,分别是:http://www.tunan.fun
,这是希望其他人通过这两个域名都能访问到该博客,它们俩在服务商的域名解析的配置中是不同的两个,分别是:
@.tunan.fun
www.tunan.fun
不安全的Http访问
做完上面的事情,就可以通过http://tunan.fun
进行访问了,但此时谷歌浏览器就会告知这是不安全的网站。
Https才是安全的访问方式,没有人愿意自己的博客网页被标记是不安全的。
接下来我们就通过「Let's Encrypt」来实现https
安全证书的安装。
Let's Encrypt
We recommend that most people with shell access use the Certbot ACME client.
这是其Getting Started
中的描述,接下来我们就会使用 Certbot 来安装证书。
选择Nginx+Linux,随后就会给出相关的安装步骤,比较简单,其中最关键的一步是Choose how you'd like to run Certbot
。
我建议直接使用第一种方式:certbot --nginx
。它会做几件事情:
- 基于现在的
nginx
配置中的server_name
来生成相应的证书(存到某个位置) - 把证书的配置写到
nginx.conf
中 - 使配置文件生效
此时再看配置文件就会额外多出一些不同的内容,我建议你,保存之前的配置文件,前后对比一下。
http {
server {
server_name tools.tunan.fun;
root /home/yaodao/my-app/my-tools/front/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.tunan.fun/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.tunan.fun/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
server_name tunan.fun www.tunan.fun;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.tunan.fun/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.tunan.fun/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
}
- 这里需要注意证书是会过期的,但没关系,写个脚本就可以了,不会写也没关系,Certbot贴心的给出了,只要耐心读完它的所有步骤。
- 如果server_name中有些域名是无效的(忘记在域名解析中设置了),那就不要为其生成证书或者先去设置一下,命令执行时会询问为哪些
server_name
生成证书。 - 实际上子域名和根域名的证书是一样,当
多个完全无关的域名
时就会生成多个证书了。 - 如果我想再加一个
server_name
并安装证书,只要加上server{}
,然后重新执行certbot --nginx
一遍就可以了。
🎉 Https 访问!
现在就可以通过https
访问你的网站了: https://www.tunan.fun.
然而万事大吉了吗?NO!!!
🫨 突然的报错
如果你的服务是前后端分离的,比如:
tunan-blog-app
- 前端基于
reac+node.js
框架,通过暴露某个端口(i.e.8080
)作为服务入口 - 后端通过
go
语言的Go Fiber
提供http
服务。
- 前端基于
tunan-tools-app
- 前端基于
vue
框架,利用生成的静态文件dist
做服务入口。 - 后端通过
java
语言的Spring Web
提供http
服务。
- 前端基于
原本,前端进行http调用的时候直接通过ip:port
或者http+域名
的方式进行后台服务调用,现在网站升级成https
的了。
此时浏览器再发起http
的方式进行网络接口调用,就会被拦截,认为这是不安全的操作。
所以还需要将后台的服务也变成https的访问。以设置tunan-tools-app
的后台服务的域名访问为例。
该服务运行在9091
端口上,想通过https://tools.tunan.fun/api/xxx
来访问。那么nginx
的配置文件增加新的location / * {} 模块
:
http {
server {
server_name tools.tunan.fun;
root /home/yaodao/my-app/my-tools/front/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://127.0.0.1:9091;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.tunan.fun/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.tunan.fun/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
……
}
映射关系如下:
完结
通过这种方式,就能物尽其用,子域名映射到不同的服务上!希望这篇文章能够帮助到正在读的你。