nginx部署相关
# 配置
跟部署相关的Nginx配置语法
# 最基本配置
cd /etc/nginx/conf.d
vi sty-8081.conf
2
输入
upstream sty{
server 127.0.0.1:8081
}
server {
#侦听的80端口
listen 80;
server_name 你的公网ip地址;
location / {
proxy_pass http://sty; #在这里设置,和upstream的名字一样
#以下是一些反向代理的配置可删除
proxy_redirect off;
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
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-Nginx-Proxy true
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# include指令在http块中的应用
在 conf/nginx.conf 文件中的http块中添加如下配置:
http{
//...
include vhost/*.conf;
server_names_hash_bucket_size 64;
}
2
3
4
5
其中vhost/*.conf
表示 vhost 文件下的所有以 .conf 结尾的文件。server_names_hash_bucket_size
是server_name
的存储大小。
为了更好管理每个Vue工程对应的部署配置,在 conf 文件夹中创建一个 vhost 文件夹,在 vhost 文件夹中根据每个Vue工程创建对应的部署配置文件;
其中 a.conf 文件代表A工程对应的部署配置文件。
再利用include
指令把 conf/vhost 文件夹中每个文件中的server块添加到 conf/nginx.conf 文件中的http块中。
# location块的配置语法
在介绍之前先阐述一个URL的构成,一个URL是有协议+域名+端口号+路径+文件名+参数+锚点构成的
当用一个URL访问一个server块创建的虚拟服务器,这个server块中的location块会用其匹配规则去匹配这个URL的路径部分,如果有一个location块匹配成功后,则执行这个location块中相关的操作。
其语法是location [=|~|~*|^~|@] pattern { ... }
,其中[=|~|~*|^~|@]
是修饰符,pattern
是匹配规则,在{ ... }
中配置相关的操作。
其中修饰符是非必须的,若没修饰符,仍然可以用pattern(匹配规则)去匹配URL路径部分。修饰符的种类及作用如下表所示:
修饰符 | 作用 |
---|---|
= | 对应的匹配规则是个字符串,表示对URL路径部分进行精确匹配,即该字符串等于URL路径部分。 |
~ | 对应的匹配规则是个正则,表示匹配时区分大小写。 |
~* | 对应的匹配规则是个正则,表示匹配时不区分大小写。 |
^~ | 对应的匹配规则是个字符串,表示匹配时要检测URL路径部分中是否含有该字符串。 |
@ | 用于定义一个location块,且该块不能被外部访问,只能被Nginx内部指令所访问。 |
此外修饰符还有另外一个作用,提高location块匹配的优先级,其优先级如下所示:
`[=]` > `[^~]` > `[~/~*]` > 无修饰符
# 匹配的大致流程:
- 第一步:优先使用
=
修饰符的location块的匹配规则去匹配,=
意味精确匹配,如果匹配上了,该location中的操作马上执行,匹配过程就此结束; - 第二步:若没匹配上,接下来去匹配那些匹配规则是字符串的location块,若被多个location块匹配上,取其中匹配规则最长的location块,若该location块的匹配规则前面有
^~
修饰符,马上执行其中操作,匹配过程结束。若该location块的匹配规则前面没有修饰符,先记录该location块继续往下匹配。 - 第三步:若匹配规则是字符串的location块没有匹配上,或者匹配上的location块的修饰符不是
^~
。那么接下来去匹配那些匹配规则是正则的location块。这里要注意如果匹配规则是正则,那么其前面一定要加上~
或~\*
修饰符,否则不起作用。 若被多个location块匹配上,则按着location块的定义顺序,取顺序最上面的location块进行匹配,马上执行其中操作,匹配过程结束。 - 第四步:若匹配规则是正则的location块没匹配上,要去看一下第二步中,若有无修饰符的location块匹配上,马上执行其中操作,匹配过程结束。若没有,匹配过程也照样结束。
关于第二步中,取其中匹配规则最长的location块举个例子说明:
server{
listen 8081;
server_name test.com;
location ^~ /doc {
return 001;
}
location ^~ /docu {
return 002;
}
}
2
3
4
5
6
7
8
9
10
执行命令curl -I test.com:8080/document
发起一个网络请求,结果是返回 002 ;
其中^~ /doc
和^~ /docu
都能匹配URL路径部分中/document
。因为/docu
字符串的长度比/doc
长,所以匹配规则为^~ /docu
的location块被匹配上。
# root指令和alias指令在location块中的区别
root
指令和alias
指令所配置的路径皆是资源所在文件夹的路径中的基础路径,把基础路径和URL的路径部分拼接一下,才会得到资源所在文件夹的真正路径。
通过root
指令和alias
指令定义的基础路径,其拼接规则是不一样的,有区别的;
在 nginx.conf 中 http 块中添加如下配置:
server{
listen 8081;
server_name test.com;
location ^~ /home {
root html;
}
location ^~ /list {
alias html;
}
location ^~ /form/ {
alias html;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
其中html
是Nginx安装目录中的html文件夹的路径。
- 当浏览器访问 test.com:8080/home/index.… (opens new window) ,被匹配规则为
/home
的location块匹配到,用root
的值拼接到URL路径/home/
前面生成访问服务器资源所在文件夹的路径:html
+/home/
=html/home/
。 - 当浏览器访问 test.com:8080/list/index.… (opens new window) ,被匹配规则为
/list
的location块匹配到,用alias
的值把URL路径/list/
中的/list
部分替换掉生成访问服务器资源所在文件夹的路径:html/
。 - 当浏览器访问 test.com:8080/form/home/i… (opens new window) ,被匹配规则为
/form/
的location块匹配到,用alias
的值把URL路径/form/home/
中的/form/
部分替换掉生成访问服务器资源所在文件夹的路径:htmlhome/
,可以看见URL路径的替换部分/form/
和location块的匹配规则/form/
一致。
在部署Vue工程时,root
和alias
一般配置为Vue工程编译打包后生成的文件夹在服务器上存放的路径。
# try_files指令在location块的应用
try_files
指令的作用是尝试查找文件。其语法是try_files file ... uri;
, 其中 file
是文件的相对路径,可以配置多个,uri
是URL路径部分。要注意文件的相对路径是相对于try_files
指令所在location块中访问服务器资源所在文件夹的路径。 Nginx会根据文件路径配置的顺序从前往后来查找,并使用第一个找到的文件的配置路径进行请求处理,如果通过配置的文件路径都没有找到对应的文件,则把最后一个配置的uri
去匹配对应的location块。
在项目中使用history模式的路由,为了避免通过URL访问到的页面不存在时,返回浏览器自带的404页面。要在location块中增加一行配置,配置如下所示:
location / {
try_files $uri $uri/ /index.html;
}
2
3
$uri
是URL的路径和文件名部分,例如访问 test.com:8080/doc/index.h… (opens new window) ,$uri
就是/doc/index.html
。
# proxy_pass指令在location块的应用
代理有正向代理和反向代理两种,都是用proxy_pass
指令来实现。
- 一句话解释正向代理,正向代理的对象是用户,用户知道访问那个服务器,而服务器不知道是哪个用户访问它。
- 一句话解释反向代理,反向代理的对象是服务器,用户不知道访问了哪个服务器,而服务器知道那个用户访问它。
# rewrite指令在location块的应用
rewrite
的作用是重定向。其语法是rewrite regex replacement [flag];
。
regex
是匹配URL路径部分的正则表达式;replacement
是重定向的地址,如果其值为文件路径时,其路径是相对路径,如果location块中未定义root
或alias
,且location块所在server块中也没有定义root
,则将Nginx安装目录中 html 文件夹的路径作为参照路径。flag
是标志位,在location块中一般使用break
,表示执行完rewrite,不会继续匹配其它location块。如果使用last
,表示执行完rewrite,会继续匹配其它location块。
# 部署
# 部署结构图
# 相关命令
scp -r dist samy@192.168.11.xxx:/home/samy/deploy/etag-web/
# 前端部署
把Vue工程部署到域名的子路径上有三种方案:
- 利用反向代理来部署;
- 利用root配置来部署;
- 利用alias配置来部署;
不管那种部署方案都需要用location块来匹配访问URL的路径部分并做处理;
# 前端构建路径设置
要部署在域名的子路径
/bbb/
上,要先更改Vue工程中的配置
用Vue CLI3搭建
把
publicPath
的值修改为子路径/bbb/
,目的是使编译打包后代码中对资源的引用路径前面加上子路径/bbb/
,在加载资源时发出的URL请求能被location块匹配到。在vue.config.js
文件中修改:module.exports = { publicPath: process.env.NODE_ENV == 'development' ? '/' : '/bbb/', }
1
2
3把路由的基路径
base
的值修改为子路径/bbb/
,在src/router/index.js
文件中修改:const router = new Router({ //... base: process.env.BASE_URL, });
1
2
3
4process.env.BASE_URL
的值就是publicPath
的值。
用Vue CLI2搭建:
把
assetsPublicPath
的值修改为子路径/bbb/
,在config/index.js
中修改如下配置:module.exports = { build: { assetsPublicPath: '/bbb/', } }
1
2
3
4
5把路由的基路径
base
的值修改为子路径/bbb/
,在src/router/index.js
文件中修改:const router = new Router({ //... base: /bbb/, });
1
2
3
4
# 利用反向代理来部署
在 conf/vhost 文件夹下创建 A.conf 来写入A工程部署到域名XXX( www.xxx.com (opens new window) )根路径上的部署配置,如下所示:
# A.conf
server {
listen 80;
server_name xxx.com;
location / {
root /home/samyz/deploy/avue/dist;
try_files $uri $uri/ /index.html;
index index.html;
}
location ^~ /bbb {
proxy_pass http://10.203.19.74:8081/;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
在 conf/vhost 文件夹下创建 B.conf 来写入B工程部署到端口为8081的服务上的部署配置,如下所示:
# B.conf
server {
listen 8001;
location / {
root /home/samyz/deploy/bvue/dist;
try_files $uri $uri/ /index.html;
index index.html;
}
}
2
3
4
5
6
7
8
9
在 conf/vhost/A.conf 文件中添加反向代理的配置,实现访问 www.xxx.com/bbb/ (opens new window) 时,通过反向代理访问 http://10.203.19.74:8081/ ,其中 10.203.19.74 为真实服务器ip地址。这样间接实现了在域名XXX( www.xxx.com (opens new window) )的子路径 /bbb/ 上部署了B工程。
# 利用root配置来部署
# A.conf
server {
listen 80;
server_name xxx.com;
location / {
root /home/samyz/deploy/avue/dist;
try_files $uri $uri/ /index.html;
index index.html;
}
location ^~ /bbb {
alias /home/samyz/deploy/bvue/dist;
try_files $uri $uri/ @router;
index index.html;
}
location @router {
root /home/samyz/deploy/bvue/dist;
rewrite ^.*$ /index.html break;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
这里用修饰符 @
创建一个内部的location块(@router),在这个location块中用rewrite
指令来解决这个问题。
# 利用alias配置来部署
# A.conf
server {
listen 80;
server_name xxx.com;
location / {
root /home/samyz/deploy/avue/dist;
try_files $uri $uri/ /index.html;
index index.html;
}
location ^~ /bbb {
root /home/samyz/deploy/bvue/;
try_files $uri $uri/ @router;
index index.html;
}
location @router {
root /home/samyz/deploy/bvue/dist;
rewrite ^.*$ /index.html break;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- 匹配规则为
/
的location块中root
所配置是A工程编译打包后生成的文件夹在服务器上存放的路径; - 匹配规则为
/bbb
的location块中root
所配置是B工程代码所在的文件夹在服务器上存放的路径; - @router的location块中的
root
所配置是B工程编译打包后生成的文件夹在服务器上存放的路径。
同时要把工程编译打包生成的文件夹名称改成和所部署域名的子路径一样。在Vue工程中可以这么配置。
用Vue CLI3搭建:在
vue.config.js
文件中修改outputDir
为bbb
;module.exports = { outputDir: 'bbb', }
1
2
3用Vue CLI2搭建:在
config/index.js
文件中修改如下配置:module.exports = { build: { //... assetsRoot: path.resolve(__dirname, '../bbb'), } }
1
2
3
4
5
6
# 相关链接
https://juejin.cn/post/6919799574253174792