使用 Nginx 部署 Vue 項目

Vue 項目在 build 之后通常都需要部署到服務(wù)器才能夠訪問,本文介紹如果使用 Nginx 部署 Vue 項目

更多精彩

首先需要說明可能存在的誤區(qū)

  1. 我這個項目是使用的 Vue + SpringBoot 實現(xiàn)前后分離的項目
  2. 也就是說在部署時,前端和后端要分別單獨部署,前端通過請求后端的接口還實現(xiàn)數(shù)據(jù)交互
  3. 一開始我是打算將 build 后的 Vue 項目直接放到 Tomcat 的 /webapps/ 目錄中,然后啟動 Tomcat
  4. 后端由于是 SpringBoot ,所以不打算借助 Tomcat ,會直接通過 java -jar xxx.jar 啟動
  5. 由于前后端分別使用了不同的服務(wù)部署,兩者之間會出現(xiàn)端口號不一致的情況
  6. 這個時候就需要使用 Nginx 來實現(xiàn)代理轉(zhuǎn)發(fā),所以我就準(zhǔn)備 使用 Nginx 將部署在 Tomcat 中的前端項目發(fā)出的請求代理轉(zhuǎn)發(fā)到通過 SpringBoot 單獨啟動的后端項目中
  7. BUT ,這個思路實際上是 不行的!??!
  8. 因為比如部署前端項目的 Tomcat ,使用的端口號是 8082 ,那么前端項目的訪問地址就會是 http://192.168.7.8?:8082/teamnote/#/ ,與之對應(yīng)的從前端項目發(fā)送出去的請求,比如請求任務(wù)列表就會是 http://192.168.7.8:8082/teamnote/api/tasks
  9. 后端項目由于是通過 SpringBoot 單獨啟動,其接收任務(wù)列表請求的接口就會是 http://192.168.7.8:2592/teamnote/api/tasks
  10. 如果使用 Nginx ,理所應(yīng)當(dāng)?shù)奈艺J(rèn)為是監(jiān)聽 8082 端口,然后將 /teamnote/api/ 開頭的請求轉(zhuǎn)發(fā)到 http://192.168.7.8:2592/teamnote/api/
  11. 看上去好像沒毛病,但當(dāng)在 Nginx 的 nginx.conf 中改完保存并重啟時,則會拋出以下錯誤
.... 0.0.0.0:8082 failed (98: Address already in use)
  1. 這是因為,8082 端口已經(jīng)被部署了前端項目的 Tomcat 使用了,Nginx 無法監(jiān)聽一個已經(jīng)被使用的端口,所以上述好像沒啥毛病的部署思路,全是錯的?。?! ,這讓我在一條死胡同里耗了一個多小時

正確的部署方式

  1. 既然是使用 Nginx 部署項目,那么就應(yīng)該直接將 Vue 項目部署到 Nginx 的服務(wù)目錄,因為 Nginx 和 Tomcat 一樣,都是服務(wù)器

將打包好的前端項目文件放到指定目錄中

  1. 一開始我會想要把打包后的項目文件放到 Nginx 默認(rèn)的目錄,但這樣實際上是不好的,項目文件完全可以放在單獨的目錄中方便統(tǒng)一管理,如下圖
    • asl-teamnote-1.0.jar 是打包好的后端項目包
    • run-backend.sh 是后端項目包的一鍵啟動腳本
    • teamnote 則是將前端項目 build 之后的 dist 目錄改名后的文件目錄
      image

修改 Nginx 配置,指向上述目錄

  1. 一般來說就是修改 Nginx 的默認(rèn)配置文件 nginx.conf 即可,但不推薦這么做,既然上面使用了單獨的目錄管理項目文件,那么這里也推薦創(chuàng)建單獨的 Nginx 配置文件來管理此項目的 Nginx 配置
  2. 在 Nginx 的默認(rèn)配置文件 nginx.conf 中,最后一行寫著 include /etc/nginx/conf.d/*.conf;
  3. 這說明只要是該目錄下文件后綴為 conf 的文件都會被自動加載到 Nginx 配置中
  4. 所以可以前往該目錄,創(chuàng)建此項目的配置文件,例如 asing1elife.conf ,如下圖
    image

編寫自定義的 Nginx 配置文件

  1. 具體配置方式參考自
server {
    # 需要被監(jiān)聽的端口號,前提是此端口號沒有被占用,否則在重啟 Nginx 時會報錯
    listen       8888;
    # 服務(wù)名稱,無所謂
    server_name  localhost;

    # 上述端口指向的根目錄
    root /opt/asing1elife/teamnote;
    # 項目根目錄中指向項目首頁
    index index.html;

    client_max_body_size 20m; 
    client_body_buffer_size 128k;

    # 根請求會指向的頁面
    location / {
      # 此處的 @router 實際上是引用下面的轉(zhuǎn)發(fā),否則在 Vue 路由刷新時可能會拋出 404
      try_files $uri $uri/ @router;
      # 請求指向的首頁
      index index.html;
    }

    # 由于路由的資源不一定是真實的路徑,無法找到具體文件
    # 所以需要將請求重寫到 index.html 中,然后交給真正的 Vue 路由處理請求資源
    location @router {
      rewrite ^.*$ /index.html last;
    }

    # 關(guān)鍵步驟,這里表示將所有的 http://192.168.7.8:8888/teamnote/api/ 開頭的請求都轉(zhuǎn)發(fā)到下面 proxy_pass 指定的鏈接中
    # 這里使用 /teamnote/api/ 而不是 /teamnote/ ,是因為前端項目本身的訪問鏈接就是 http:192.168.7.8:8888/teamnote/
    # 為了防止在訪問頁面時請求就被 Nginx 代理轉(zhuǎn)發(fā),這里需要更具體的配置,才能和前端訪問請求區(qū)分開
    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

  1. 使用 nginx -s reload 可以重新加載 Nginx 的配置文件,但如果配置文件有錯,不一定會拋出異常
  2. 使用 nginx -s stop 先停止 Nginx 服務(wù),再使用 nginx 嘗試啟動 Nginx 服務(wù),如果配置文件有異常,則會拋出異常告知啟動失敗

更新前端項目包

  1. 將更新后的前端項目打包,直接傳到之前的前端文件目錄即可,Nginx 不需要重啟
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容