next.js、nuxt.js等服務端渲染框架構建的專案部署到伺服器,並用PM2守護程式

一探發表於2019-02-16

前端渲染:vue、react等單頁面專案應該這樣子部署到伺服器

貌似從前幾年,前後端分離逐漸就開始流行起來,把一些渲染計算的工作拋向前端以便減輕服務端的壓力,但為啥現在又開始流行在服務端渲染了呢?如vue全家桶或者react全家桶,都推薦通過服務端渲染來實現路由。搞得我們慌得不行,不禁讓我想起一句話:從來沒有任何一門語言的技術棧像Javascript一樣,學習者拼盡全力也不讓精通。沒辦法,流行,我們們就得學!

前斷時間寫了一篇vue、react等單頁面專案應該這樣子部署到伺服器,結果反響不錯!最近好多朋友私信或邀請問很多關於next.js和nuxt.js的問題,比如關於nextjs 和 nuxtjs如何部署?pm2如何配合?…在這裡我們就一起討論下在伺服器上使用PM2守護next.js、nuxt.js等服務端渲染框架構建的專案!該篇我們只討論服務端渲染應用部署靜態應用部署就是我前段時間寫的vue、react等單頁面專案應該這樣子部署到伺服器

Nginx配置

既然是應用,我們就應該有域名,在這裡我們以 nginx配置 為例,簡單配置如下:
Next域名:http://next.sosout.com/
Nuxt域名:http://nuxt.sosout.com/

http {
    ....  # 省略其他配置
   
    server {
        listen 80;
        server_name  *.sosout.com;
        
        if ($host ~* "^(.*?).sosout.com$") {
            set $domain $1;
        }

        location / {
            if ($domain ~* "next") {
                root /mnt/html/next;
            }
            if ($domain ~* "nuxt") {
                root /mnt/html/nuxt;
            }
            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-Forwarded-Proto  $scheme;
        }
        access_log  /mnt/logs/nginx/access.log  main;
    }

    #tcp_nopush     on;

    include /etc/nginx/conf.d/*.conf;
}

Nginx反向代理

由於服務端渲染的各個應用埠號各不相同,因此這個時候我們就需要反向代理了,配置如下:

#通過upstream nodejs 可以配置多臺nodejs節點,做負載均衡
#keepalive 設定存活時間。如果不設定可能會產生大量的timewait
#proxy_pass 反向代理轉發 http://nodejs

upstream nodenext {
    server 127.0.0.1:3001; #next專案 監聽埠
    keepalive 64;
}

server {
    listen 80;
    server_name next.sosout.com;
    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;  
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Nginx-Proxy true;
        proxy_cache_bypass $http_upgrade;
        proxy_pass http://nodenext; #反向代理
    }
}

upstream nodenuxt {
    server 127.0.0.1:3002; #nuxt專案 監聽埠
    keepalive 64;
}

server {
    listen 80;
    server_name nuxt.sosout.com;
    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;  
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Nginx-Proxy true;
        proxy_cache_bypass $http_upgrade;
        proxy_pass http://nodenuxt; #反向代理
    }
}

伺服器的準備工作已完成,接下來我們就分別看看Next.js和Nuxt.js服務端渲染應用如何部署?

Next.js服務端渲染應用部署

部署 Next.js 服務端渲染的應用不能直接使用 next 命令,而應該先進行編譯構建,然後再啟動 Next 服務,官方通過以下兩個命令來完成:

next build
next start

官方推薦的 package.json 配置如下:

{
  "name": "my-app",
  "dependencies": {
    "next": "latest"
  },
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  }
}

而我更推薦如下配置,稍後你會發現這樣和 pm2 一起使用更方便,自動化部署也方便:

{
  "name": "my-app",
  "dependencies": {
    "next": "latest"
  },
  "scripts": {
    "dev": "next",
    "start": "next start -p $PORT",
    "build": "next build && PORT=3001 npm start"
  }
}

next.js服務端渲染應用部署這樣就完成了,官方先後執行 npm run build 、npm start 即可完成部署。而我這邊只要執行 npm run build ,其實我只是把兩個合併成一個,並設定了埠以便區別其他應用,避免埠占用!

接下來簡單的說一下next這幾個命令:
next: 啟動一個熱載入的Web伺服器(開發模式)
next build: 利用webpack編譯應用,壓縮JS和CSS資源(釋出用)。
next start: 以生成模式啟動一個Web伺服器 (next build 會先被執行)。

Nuxt.js服務端渲染應用部署

其實部署 Nuxt.js 服務端渲染的應用和 Next.js 極其相似!在這裡我就把程式碼粘貼上貼,複復制制,改改寫寫。。。。
Nuxt.js 服務端渲染的應用不能直接使用 nuxt 命令,而應該先進行編譯構建,然後再啟動 Nuxt 服務,官方通過以下兩個命令來完成:

nuxt build
nuxt start

官方推薦的 package.json 配置如下:

{
  "name": "my-app",
  "dependencies": {
    "nuxt": "latest"
  },
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start"
  }
}

而我更推薦如下配置,稍後你會發現這樣和 pm2 一起使用更方便,自動化部署也方便:

{
  "name": "my-app",
  "dependencies": {
    "nuxt": "latest"
  },
  "scripts": {
    "dev": "nuxt",
    "start": "PORT=3002 nuxt start",
    "build": "nuxt build && npm start"
  }
}

nuxt.js服務端渲染應用部署這樣就完成了,官方先後執行 npm run build 、npm start 即可完成部署。而我這邊只要執行 npm run build ,其實我只是把兩個合併成一個,並設定了埠以便區別其他應用,避免埠占用!

接下來簡單的說一下nuxt這幾個命令:
nuxt: 啟動一個熱載入的Web伺服器(開發模式)
nuxt build: 利用webpack編譯應用,壓縮JS和CSS資源(釋出用)。
nuxt start: 以生成模式啟動一個Web伺服器 (nuxt build 會先被執行)。

PM2守護程式

Next.js使用pm2,進入對應的應用目錄,執行以下命令:

pm2 start npm --name "my-next" -- run build

Nuxt.js使用pm2,進入對應的應用目錄,執行以下命令:

pm2 start npm --name "my-nuxt" -- run build

使用pm2時,把兩個部署命令合成一個更方便!執行完pm2的啟動命令後,我們用 pm2 list 檢視一下程式列表,我截一下我個人伺服器的pm2列表:

clipboard.png

以後您就可以用pm2進行維護了,比如我們的next應用更改了程式碼,因為當時建立時給next應用命名的程式名稱為 my-next ,因此我們可以直接使用 pm2 reload my-next 進行過載。接下來我就簡單介紹一下pm2,如果有需要,我可以另寫一篇關於pm2的文章!

pm2 簡單介紹

pm2是nodejs的一個帶有負載均衡功能的應用程式管理器的模組,類似有Supervisor,forever,用來進行程式管理。

一、安裝:
npm install pm2 -g
二、啟動:
pm2 start app.js
pm2 start app.js --name my-api       #my-api為PM2程式名稱
pm2 start app.js -i 0                #根據CPU核數啟動程式個數
pm2 start app.js --watch             #實時監控app.js的方式啟動,當app.js檔案有變動時,pm2會自動reload
三、檢視程式:
pm2 list
pm2 show 0 或者 # pm2 info 0         #檢視程式詳細資訊,0為PM2程式id 
四、監控:
pm2 monit
五、停止:
pm2 stop all                         #停止PM2列表中所有的程式
pm2 stop 0                           #停止PM2列表中程式為0的程式
六、過載:
pm2 reload all                       #過載PM2列表中所有的程式
pm2 reload 0                         #過載PM2列表中程式為0的程式
七、重啟:
pm2 restart all                      #重啟PM2列表中所有的程式
pm2 restart 0                        #重啟PM2列表中程式為0的程式
八、刪除PM2程式:
pm2 delete 0                         #刪除PM2列表中程式為0的程式
pm2 delete all                       #刪除PM2列表中所有的程式
九、日誌操作:
pm2 logs [--raw]                     #Display all processes logs in streaming
pm2 flush                            #Empty all log file
pm2 reloadLogs                       #Reload all logs
十、升級PM2:
npm install pm2@lastest -g           #安裝最新的PM2版本
pm2 updatePM2                        #升級pm2
十一、更多命令引數請檢視幫助:
pm2 --help
十二、PM2目錄結構:
  • 1、預設的目錄是:當前用於的家目錄下的.pm2目錄(此目錄可以自定義,請參考:十三、自定義啟動檔案),詳細資訊如下:
$HOME/.pm2                   #will contain all PM2 related files
$HOME/.pm2/logs              #will contain all applications logs
$HOME/.pm2/pids              #will contain all applications pids
$HOME/.pm2/pm2.log           #PM2 logs
$HOME/.pm2/pm2.pid           #PM2 pid
$HOME/.pm2/rpc.sock          #Socket file for remote commands
$HOME/.pm2/pub.sock          #Socket file for publishable events
$HOME/.pm2/conf.js           #PM2 Configuration
十三、自定義啟動檔案:
  • 1、建立一個test.json的示例檔案,格式如下:
{
  "apps":
    {
      "name": "test",
      "cwd": "/data/wwwroot/nodejs",
      "script": "./test.sh",
      "exec_interpreter": "bash",
      "min_uptime": "60s",
      "max_restarts": 30,
      "exec_mode" : "cluster_mode",
      "error_file" : "./test-err.log",
      "out_file": "./test-out.log",
      "pid_file": "./test.pid"
      "watch": false
    }
}
  • 2、引數說明:
apps:json結構,apps是一個陣列,每一個陣列成員就是對應一個pm2中執行的應用
name:應用程式的名稱
cwd:應用程式所在的目錄
script:應用程式的指令碼路徑
exec_interpreter:應用程式的指令碼型別,這裡使用的shell,預設是nodejs
min_uptime:最小執行時間,這裡設定的是60s即如果應用程式在60s內退出,pm2會認為程式異常退出,此時觸發重啟max_restarts設定數量
max_restarts:設定應用程式異常退出重啟的次數,預設15次(從0開始計數)
exec_mode:應用程式啟動模式,這裡設定的是cluster_mode(叢集),預設是fork
error_file:自定義應用程式的錯誤日誌檔案
out_file:自定義應用程式日誌檔案
pid_file:自定義應用程式的pid檔案
watch:是否啟用監控模式,預設是false。如果設定成true,當應用程式變動時,pm2會自動過載。這裡也可以設定你要監控的檔案。

由於工作原因,一直沒光顧segmentfault,收到很多關於部署的私信和評論,特此補充以下內容:

部署(以nuxt為例)

基礎模板的部署方式

何為基礎模板?使用了 vue init nuxt-community/starter-template <project-name> 進行搭建的!

第一步,打包

在執行 npm run build 的時候, nuxt 會自動打包。

第二步,選擇要部署的檔案(社友最關心的步驟):

  • .nuxt/ 資料夾
  • package.json 檔案
  • nuxt.config.js 檔案(如果你配置proxy等,則需要上傳這個檔案,建議把它傳上去)

第三步,啟動你的nuxt:

使用pm2啟動你的nuxt.js:

$ npm install // or yarn install 如果未安裝依賴或依賴有更改
$ pm2 start npm --name "my-nuxt" -- run start

相關文章