10.部署
部落格寫完後,當然是要釋出到網路上的。如果想要部署到伺服器上,則需編譯構建成靜態檔案,然後將其上傳到伺服器上的路徑(該路徑由我們自己決定),然後在 web 伺服器(Nginx 等)上配置訪問路徑即可
這裡說的是有自己伺服器的情況,如果嫌麻煩和沒預算可以使用 GitHub Pages 服務
構建靜態檔案
VuePress 提供了 vuepress build docs
命令來構建,也就是我們之前在 package.json 裡配置的 docs:build
:
"scripts": {
"docs:dev": "vuepress dev docs --temp .temp",
"docs:build": "vuepress build docs",
},
我們在命令列裡執行,結果如下:
> npm run docs:build
> vuepress-learn@1.0.0 docs:build
> vuepress build docs
wait Extracting site metadata...
tip Apply theme @vuepress/theme-default ...
tip Apply plugin container (i.e. "vuepress-plugin-container") ...
tip Apply plugin @vuepress/register-components (i.e. "@vuepress/plugin-register-components") ...
tip Apply plugin @vuepress/active-header-links (i.e. "@vuepress/plugin-active-header-links") ...
tip Apply plugin @vuepress/search (i.e. "@vuepress/plugin-search") ...
tip Apply plugin @vuepress/nprogress (i.e. "@vuepress/plugin-nprogress") ...
√ Client
Compiled successfully in 14.78s
√ Server
Compiled successfully in 4.35s
wait Rendering static HTML...
success Generated static files in docs\.vuepress\dist.
我們觀察最後一行,VuePress 告訴我們成功生成了靜態檔案在這個目錄:docs.vuepress\dist
。我們無需關心裡面的內容,只需將整個目錄上傳到伺服器上即可(FTP 或者壓縮後上傳)
Nginx 配置
這裡已經假設讀者有了伺服器和安裝了 Nginx。如果不知道什麼是 Nginx,可以參考我的部落格:伺服器軟體
以筆者部署的過程為例:
-
將 dist 資料夾裡的內容上傳到/opt/myblog 目錄下(可以壓縮 dist 目錄為壓縮包,然後上傳再解壓)
-
配置 Nginx:
location / { root /opt/myblog; index index.html index.htm; }
-
重啟 Nginx
訪問伺服器 IP,即可看到部落格內容,並且可以正常跳轉等,和本地執行的效果一致:
GitHub Pages
一個伺服器後續的續費高達幾千元一年;如果不想要購買伺服器和配置域名等等,可以使用 GitHub Pages,也是不少人在使用的方式。
GitHub 是什麼就不多解釋了。簡單來說 GitHub 就是一個 Git 專案的託管服務平臺,上面有很多知名專案。其中,每個專案都有一個主頁,列出專案的原始檔,例如 Linux:
但是對於一個新手來說,看到一大堆原始碼,只會讓人頭暈腦漲,不知何處入手。他希望看到的是,一個簡明易懂的網頁,說明每一步應該怎麼做。
因此,Github 就設計了 Pages 功能,允許使用者自定義專案首頁,用來替代預設的原始碼列表。所以,Github Pages 可以被認為是使用者編寫的、託管在 Github 上的靜態網頁。
博主沒有用過該功能,因此不展開來講,感興趣的讀者可參考:
- 一篇帶你用 VuePress + Github Pages 搭建部落格_JavaScript_冴羽_InfoQ 寫作社群
- 搭建一個免費的,無限流量的 Blog----github Pages 和 Jekyll 入門 - 阮一峰的網路日誌
自動化部署
如果每次修改了部落格內容,都要重新構建、然後上傳到伺服器上,未免也太麻煩了。為此,我們可以用一些第三方工具,自動將打包後的檔案上傳到伺服器上:
- scp2:是一個純 js 編寫的 ssh2 協議的 Linux 遠端檔案複製實現
- ora:是一個優雅的用於命令列 Loading 的 spinner,簡單來說就是用來實現命令列環境的 loading 效果,和顯示各種狀態的圖示等,美觀一點。
安裝依賴:
npm i scp2 ora@5.0
ora6.0 以上版本不支援 require 方式引入,因為在 node 中使用,使用 5.0 版本
在專案裡新建兩個檔案:
- deploy.js:用於編寫部署命令
- serverInfo.json:用於存放伺服器資訊(由於本部落格是開源的,不方便將伺服器 IP 和密碼等敏感資訊公開)
deploy.js 的內容:
const fs = require('fs')
const scpClient = require('scp2')
const ora = require('ora')
const serverInfo = JSON.parse(fs.readFileSync('serverInfo.json'))
const loading = ora('正在部署至 ' + serverInfo.host )
loading.start()
scpClient.scp('./docs/.vuepress/dist/', serverInfo ,(err)=>{
loading.stop()
if(err) {
console.log('部署失敗')
throw err
}else {
console.log('部署成功')
}
})
serverInfo.json:存放伺服器資訊,注意在 .gitignore 檔案裡新增 serverInfo.json,不要將敏感資訊公開了。讀者需按需修改這些資訊
{
"host":"替換成你的IP",
"port":"22",
"username":"替換成你的使用者名稱",
"password":"替換成你的密碼",
"path":"/opt/myblog"
}
在 package.json 中的 script 中新增 deploy 命令:
"scripts": {
...
"deploy": "npm run docs:build && node ./deploy.js",
...
},
測試:可以刪除之前的/opt/myblog 目錄裡的檔案
$ cd /opt
$ rm -r myblog/
然後在命令列裡執行 npm run deploy
,觀察是否正常部署了。
> node .\deploy.js
部署成功
注意:
- 後續想要部署,直接執行命令即可,會覆蓋之前的部落格內容。
- 使用 GitHub Pages 也可以實現自動化部署,這裡不展開,可參考:GET 新技能!自己的網站突然就不香了 第 3.2 節。
- 讀者也可以在伺服器上,使用 git clone 拉取專案,然後 npm run docs:build 來執行,不過這樣也很麻煩。
使用 GitHub Action
什麼是 GitHub Action?這裡引用阮一峰大佬的說明:GitHub Actions 入門教程 - 阮一峰的網路日誌
大家知道,持續整合由很多操作組成,比如抓取程式碼、執行測試、登入遠端伺服器,釋出到第三方服務等等。GitHub 把這些操作就稱為 actions。
很多操作在不同專案裡面是類似的,完全可以共享。GitHub 注意到了這一點,想出了一個很妙的點子,允許開發者把每個操作寫成獨立的指令碼檔案,存放到程式碼倉庫,使得其他開發者可以引用。
如果你需要某個 action,不必自己寫複雜的指令碼,直接引用他人寫好的 action 即可,整個持續整合過程,就變成了一個 actions 的組合。這就是 GitHub Actions 最特別的地方。
希望讀者看完阮一峰大大的部落格後再往下看。
簡單來說,就是我們可以使用別人寫好的功能,在每次程式碼推送到 Git 後,GitHub 會自動幫助我們完成編譯構建,自動上傳到伺服器上,重啟服務等等操作
一句話:可以實現提交程式碼到伺服器上後,自動更新部落格。俗稱持續整合、自動化部署。讀者也可使用 Gitee Action。接下來我們來實踐下。
伺服器準備
首先是伺服器得準備下環境,安裝 rsync,讀者使用的 Centos,root 使用者,安裝命令如下:
yum install rsync
然後在伺服器上生成公鑰和私鑰,用來授權
$ ssh-keygen -t rsa -C "peterjxl@qq.com"
然後一直回車即可,執行情況:
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Pt6bEV/LpmNU5ibmsyJjEstK4DHL2kjAaQvNbz8urok peterjxl@qq.com
The key's randomart image is:
+---[RSA 2048]----+
| |
| |
| |
|.o. o |
|o+* S . +. |
|+o.* .. o+oo. |
| o+ +. oo .+.o+ |
|.= +..=.+o.o=o |
|E +oo+o+.o++o+ |
+----[SHA256]-----+
可以看到公鑰和私鑰的位置。id_rsa 就是私鑰,id_rsa.pub 是公鑰。我們需要用到私鑰的內容:
cat /root/.ssh/id_rsa
筆者這裡就不貼出來了,也算是一種敏感資訊
然後修改本機關於 ssh 的一些配置:如此便完成了公鑰的安裝。
$ cd /root/.ssh
$ cat id_rsa.pub >> authorized_keys
開啟金鑰登入功能:編輯 /etc/ssh/sshd_config 檔案,在檔案末尾新增如下幾行:
$ RSAAuthentication yes
$ PubkeyAuthentication yes
$ PermitRootLogin yes
最後,重啟 SSH 服務:
$ service sshd restart
GitHub 準備
在專案所在的倉庫中配置: 開啟 Settings->Secrets->New secret
然後將上一步的私鑰內容新增進去:
我們再新建一個 secret,名字為 MY_SERVER_IP
,值為我們的伺服器的 IP,IP 也是一種敏感欄位。
流水線配置
接下來我們就可以配置流水線了。新建 .github/workflows 資料夾,然後再新建 main.yml,內容如下:
name: Deploy My Server
on:
push:
branches:
- master # 只在master上push觸發部署
jobs:
deploy:
runs-on: ubuntu-latest # 使用ubuntu系統映象執行自動化指令碼
steps: # 自動化步驟
#下載程式碼倉庫
- uses: actions/checkout@v1
# 使用action庫,安裝node
- name: use Node.js # 使用action庫 actions/setup-node安裝node
uses: actions/setup-node@v3
with:
node-version: 16
# 安裝依賴
- name: npm install
run: npm install
#打包專案
- name: Build
run: npm run docs:build
#部署到伺服器
- name: Deploy to Staging My server
uses: easingthemes/ssh-deploy@v2.1.6
env:
# 使用GitHub倉庫裡的secret設定的值
SSH_PRIVATE_KEY: ${{ secrets.MY_SERVER_PRIVATE_KEY }}
# 源目錄,編譯後生成的檔案目錄
SOURCE: './docs/.vuepress/dist/'
#伺服器公網地址
REMOTE_HOST: ${{ secrets.MY_SERVER_IP }}
#伺服器使用者名稱-一般預設root
REMOTE_USER: 'root'
#伺服器中,程式碼部署的位置
TARGET: '/opt/myblog'
#去除的檔案
EXCLUDE: "/dist/, /node_modules/"
這裡簡單說明下檔案的內容
- 第一行:本次流水線的名字,可自行更換
- 第 3~6 行:說明只有當 master 分支有提交到遠端庫(push)的時候,才更新(也就是執行本次流水線)
- 第 8 行:jobs,本次我們只用了一個 job,也就是第 9 行的 job
- 第 10 行:指定要在哪個作業系統的環境下編譯出包(一般是 Linux)
- 接下來就是 deploy 這個 job 的 steps,每個 step 做了不同的事情,例如安裝 node,然後安裝依賴和執行構建命令
- 第 31 行開始就是一些環境變數的設定,例如讀取我們上一小節設定的 IP 和私鑰資訊
測試流水線
每次提交程式碼到遠端倉庫,這條流水線就會執行:可以在 GitHub 專案的 Actions 選項卡里檢視
我們點選本次執行的 workflow,可以看到目前正在執行的 job:
再點進去,就可以看到這個 job 裡的 step 執行情況:打勾的說明已完成,黃色的轉圈圈的表示還在執行中
如果流水線執行失敗了,會有郵件告知,並且可以在 Action 裡檢視失敗的原因。
還可以重跑失敗的 jobs:
部署失敗:babel-preset-app
如果你遇到了 GitHub Action 部署失敗了,報錯資訊類似這樣的:
2023-02-18T12:11:00.0564591Z [BABEL] Note: The code generator has deoptimised the styling of /home/runner/work/vuepress-learn/vuepress-learn/node_modules/lodash/lodash.js as it exceeds the max of 500KB.
2023-02-18T12:11:18.4372148Z [success] [webpackbar] Server: Compiled successfully in 31.22s
2023-02-18T12:11:27.6215689Z [success] [webpackbar] Client: Compiled with some errors in 40.43s
2023-02-18T12:11:27.8557348Z (undefined) ./node_modules/@vuepress/core/.temp/style.styl
2023-02-18T12:11:27.8558854Z Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
這是因為 @vue/babel-preset-app
的版本問題,解決方法:
npm i @vue/babel-preset-app@4.5.18
更多參考:fresh new 1.x project fails to build (but dev works OK) · Issue #3065 · vuejs/vuepress
部署失敗:JavaScript heap out of memory
當你的部落格數量越來越多,那麼構建時需要的記憶體也越來越多,最後你可能會發現記憶體不夠:
<--- JS stacktrace --->
FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory
1: 0xb090e0 node::Abort() [node]
2: 0xa1b70e [node]
3: 0xce19d0 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
4: 0xce1d77 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
5: 0xe993e5 [node]
.....
解決方法:構建前設定記憶體引數,例如在 package.json 中新增:
"scripts": {
"build": "node --max_old_space_size=8192 ./node_modules/vuepress/cli.js build docs"
}
注:方法來自二丫講梵的部落格專案。
其他部署方式
如果你生成金鑰的時候,輸入了密碼進行保護:
$ ssh-keygen
...
Enter passphrase (empty for no passphrase): # In here I input a password
那麼部署的時候可能會報錯(因為沒密碼),目前暫無找到其他方法;一般是用沒有密碼保護的金鑰來部署。
如果你不想用金鑰登入,而是用密碼登入,可以用這個 action:appleboy/scp-action: GitHub Action that copy files and artifacts via SSH.
使用思源筆記外掛
如果你有使用思源筆記,還可以使用 terwer 開發的思源筆記外掛:sy-post-publisher,
獲取原始碼
本文介紹了幾種部署方式,最推薦的是使用 GitHub Action,非常方便,一勞永逸。
為了寫本系列的部落格,博主特地新建了一個專案用於演示,相關程式碼已放到 Gitee 和 GitHub 上。
並且,不同功能建立了不同分支,想要獲取本篇文章演示的原始碼只需切換分支即可!
例如,你想執行本篇文章所建立的部落格,可以這樣做:
- 開啟命令列
- 拉取程式碼:
git clone git@gitee.com:peterjxl/vuepress-learn.git
(也可拉取 GitHub 的) - 跳轉目錄:
cd vuepress-learn
- 切換分支:
git switch -c VuePressDemo6Deploy origin/VuePressDemo6Deploy
- 安裝依賴:
npm i
- 執行部落格:
npm run docs:dev
參考
- 前端專案自動化部署_前端自動化部署_眾生皆苦唯有我甜的部落格-CSDN 部落格
- 透過 GitHub Actions 自動部署 vuepresss 專案到雲伺服器_居無何的部落格-CSDN 部落格_vuepress 部署在伺服器上
- rsync exited with code 255.Load key “...“: invalid format Permission denied, please try again._rsync 255_滄州刺史的部落格-CSDN 部落格