nginx部署前端应用

3,395 阅读3分钟

基础步骤

前端项目打包

首先需要有一个前端项目,比如这里是vue项目,通过vue脚手架,简单搭建一个vue项目,然后执行yarn build打包,将dist包放在远程服务器某一个目录下,比如是/home/web/vue-test

服务器上编写nginx配置文件,并重启

在/usr/local/nginx/conf.d目录下编写配置文件,vue-dev-server.conf

server{
   # 监听的端口号
   listen  80;

   # 服务名称
   server_name  域名;

   # 文件大小限制
   client_max_body_size 502M;

   # 配置根目录的地址是以nginx下的html文件夹为根目录来查找的,此处为前端项目制品包目录
   root /home/web/vue-test;

   # 添加request-header自定义参数时,可以通过指定该属性
   underscores_in_headers on;

   # 配置默认的主页显示
   location / {
     index  index.html; // hash模式只配置访问html就可以
     try_files $uri $uri/ /index.html; // history模式下
   }

   # 正则匹配css文件
   location ^~ /api/ {
     proxy_pass http://服务端IP地址:7007/; # 转发
   }
   location ~ .*.(css)$ {
     add_header Content-Type "text/css; charset=utf-8"; # 设置响应头信息给浏览器
   }
}

编写完nginx配置文件之后,执行如下操作即可,这里使用docker启动的nginx服务, nginx添加和以前相同, 只是生效方式上有差别

  1. /usr/local/nginx/conf.d 新增一个 .conf 的配置文件: 务必保证符合 nginx配置文件语法, 端口范围请保持docker-composer.yaml监听端口范围内, 如果例外, 请单独更改docker-composer.yaml中port
  2. 进入nginx容器执行生效命令:
# 进入 nginx docker 容器
$ docker exec -it system-nginx bash

# 以下命令都是在容器内部执行的
# 确认 nginx 配置是否合法
root@d0e1c90d0809:/# nginx -t

# 重新生效 nginx 配查
root@d0e1c90d0809:/# nginx -s reload

docker-compose.yml文件内容如下所示

version: "3.9"
services:
  nginx:
    container_name: system-nginx
    image: nginx:latest
    ports:
      - "80:80"
      - "443:443"
      - "7006:7006"
    volumes:
      - /usr/local/nginx:/etc/nginx
      - /home:/home

然后访问域名即可在测试环境正常访问啦

遇到的问题

问题一:配置后访问http://服务器IP地址:7006/显示无法访问

排查:之前编写的nginx配置文件如下,最终发现端口范围没有在docker-composer.yaml

server {
  # 监听的端口号
  listen  7006;

  # 服务名称
  server_name  IP地址;
  ...
}

解决:更改docker-composer.yaml 中 port

version: "3.9"
services:
  nginx:
    ...
    ports:
      - "7006:7006" # 添加端口映射
    ...

说明

  • 为了通过域名访问,修改了nginx中listen为80端口,server_name为域名,即不同域名最终可映射到服务器IP的80端口

问题2:部署到服务器IP上之后,访问域名,登录之后页面一直跳转登录

排查:刚开始一直以为是服务器IP上获取token那块逻辑有问题,以为token拿不到,但是本地是正常的,部署之后有问题,看了好久,最后通过打断点发现走了全局异常捕捉,即后端接口返回401,鉴权失败了,跳转到登录了;但是单独通过 http://服务器IP:7007/接口名称 访问接口是正常的,通过域名http://域名/api/接口名称访问401,于是猜测访问后端接口时是不是没有拿到request headers中的test_token,但是查看network时,test_token是有的,在这里有卡了很久,最后经过一系列操作想是不是通过nginx时request headers中的test_token是不是被拦截过滤掉了,经过校验,发现真是的

解决:通过nginx中设置underscores_in_headers on或者修改test_token,该字段不符合nginx的规范,被过滤掉了,因为相对于其余的参数,该参数写法和其他不一样,即别的首字母都是大写,中间通过'-'分隔,我的首字母都是小写,中间通过'_'分隔

说明

  • proxy_pass中携带/和不携带/的区别
location ^~ /api/ {
   proxy_pass http://服务器IP:7007/; # 转发
}
// 1. 携带/: proxy_pass后面的地址如果携带/的话,访问服务器接口时会把/api去掉后面拼上后端真实的接口;等同于nginx中如下配置
rewrite ^/api/v1/(.*)$ /$1 break;
// 2.不携带/: 访问服务器接口时不会把/api去掉
  • request headers中添加参数时一定要符合规范,和其余参数形式一样,避免一些不必要的问题

nginx常用命令

  • 将本地包上传到远程服务器
scp -r 本地目录 root@IP:远程服务器目录

  • 通过mv命令将服务器上包移动到指定目录下
mv 远程服务器目录1/文件 远程服务器目录2
  • 解压.tar.gz文件,解压之前可执行删除命令rm -rf *删除文件夹下所有文件
tar -xvf xxx.tar.gz -C ./