使用 Nginx 部署 Vue 项目
2019-05-31 本文已影响173人
asing1elife
Vue 项目在 build 之后通常都需要部署到服务器才能够访问,本文介绍如果使用 Nginx 部署 Vue 项目
更多精彩
- 更多技术博客,请移步 IT人才终生实训与职业进阶平台 - 实训在线
首先需要说明可能存在的误区
- 我这个项目是使用的 Vue + SpringBoot 实现前后分离的项目
- 也就是说在部署时,前端和后端要分别单独部署,前端通过请求后端的接口还实现数据交互
- 一开始我是打算将 build 后的 Vue 项目直接放到 Tomcat 的 /webapps/ 目录中,然后启动 Tomcat
- 后端由于是 SpringBoot ,所以不打算借助 Tomcat ,会直接通过
java -jar xxx.jar
启动 - 由于前后端分别使用了不同的服务部署,两者之间会出现端口号不一致的情况
- 这个时候就需要使用 Nginx 来实现代理转发,所以我就准备 使用 Nginx 将部署在 Tomcat 中的前端项目发出的请求代理转发到通过 SpringBoot 单独启动的后端项目中
- BUT ,这个思路实际上是 不行的!!!
- 因为比如部署前端项目的 Tomcat ,使用的端口号是 8082 ,那么前端项目的访问地址就会是
http://192.168.7.8�:8082/teamnote/#/
,与之对应的从前端项目发送出去的请求,比如请求任务列表就会是http://192.168.7.8:8082/teamnote/api/tasks
- 后端项目由于是通过 SpringBoot 单独启动,其接收任务列表请求的接口就会是
http://192.168.7.8:2592/teamnote/api/tasks
- 如果使用 Nginx ,理所应当的我认为是监听 8082 端口,然后将
/teamnote/api/
开头的请求转发到http://192.168.7.8:2592/teamnote/api/
中 - 看上去好像没毛病,但当在 Nginx 的 nginx.conf 中改完保存并重启时,则会抛出以下错误
.... 0.0.0.0:8082 failed (98: Address already in use)
- 这是因为,8082 端口已经被部署了前端项目的 Tomcat 使用了,Nginx 无法监听一个已经被使用的端口,所以上述好像没啥毛病的部署思路,全是错的!!! ,这让我在一条死胡同里耗了一个多小时
正确的部署方式
- 既然是使用 Nginx 部署项目,那么就应该直接将 Vue 项目部署到 Nginx 的服务目录,因为 Nginx 和 Tomcat 一样,都是服务器
将打包好的前端项目文件放到指定目录中
- 一开始我会想要把打包后的项目文件放到 Nginx 默认的目录,但这样实际上是不好的,项目文件完全可以放在单独的目录中方便统一管理,如下图
- asl-teamnote-1.0.jar 是打包好的后端项目包
- run-backend.sh 是后端项目包的一键启动脚本
-
teamnote 则是将前端项目 build 之后的 dist 目录改名后的文件目录
image
修改 Nginx 配置,指向上述目录
- 一般来说就是修改 Nginx 的默认配置文件 nginx.conf 即可,但不推荐这么做,既然上面使用了单独的目录管理项目文件,那么这里也推荐创建单独的 Nginx 配置文件来管理此项目的 Nginx 配置
- 在 Nginx 的默认配置文件 nginx.conf 中,最后一行写着
include /etc/nginx/conf.d/*.conf;
- 这说明只要是该目录下文件后缀为 conf 的文件都会被自动加载到 Nginx 配置中
- 所以可以前往该目录,创建此项目的配置文件,例如 asing1elife.conf ,如下图
image
编写自定义的 Nginx 配置文件
server {
# 需要被监听的端口号,前提是此端口号没有被占用,否则在重启 Nginx 时会报错
listen 8888;
# 服务名称,无所谓
server_name localhost;
# 上述端口指向的根目录
root /opt/asing1elife/teamnote;
# 项目根目录中指向项目首页
index index.html;
client_max_body_size 20m;
client_body_buffer_size 128k;
# 根请求会指向的页面
location / {
# 此处的 @router 实际上是引用下面的转发,否则在 Vue 路由刷新时可能会抛出 404
try_files $uri $uri/ @router;
# 请求指向的首页
index index.html;
}
# 由于路由的资源不一定是真实的路径,无法找到具体文件
# 所以需要将请求重写到 index.html 中,然后交给真正的 Vue 路由处理请求资源
location @router {
rewrite ^.*$ /index.html last;
}
# 关键步骤,这里表示将所有的 http://192.168.7.8:8888/teamnote/api/ 开头的请求都转发到下面 proxy_pass 指定的链接中
# 这里使用 /teamnote/api/ 而不是 /teamnote/ ,是因为前端项目本身的访问链接就是 http:192.168.7.8:8888/teamnote/
# 为了防止在访问页面时请求就被 Nginx 代理转发,这里需要更具体的配置,才能和前端访问请求区分开
location /teamnote/api/ {
# 后端的真实接口
proxy_pass http://192.168.7.8:2592/teamnote/api/;
proxy_redirect off;
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 Cookie $http_cookie;
# for Ajax
#fastcgi_param HTTP_X_REQUESTED_WITH $http_x_requested_with;
proxy_set_header HTTP-X-REQUESTED-WITH $http_x_requested_with;
proxy_set_header HTTP_X_REQUESTED_WITH $http_x_requested_with;
proxy_set_header x-requested-with $http_x_requested_with;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 128k;
proxy_buffers 32 32k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
}
}
重新启动 Nginx
- 使用
nginx -s reload
可以重新加载 Nginx 的配置文件,但如果配置文件有错,不一定会抛出异常 - 使用
nginx -s stop
先停止 Nginx 服务,再使用nginx
尝试启动 Nginx 服务,如果配置文件有异常,则会抛出异常告知启动失败
更新前端项目包
- 将更新后的前端项目打包,直接传到之前的前端文件目录即可,Nginx 不需要重启