使用GitHub Actions自動部署前端到伺服器
使用GitHub Actions自動部署前端到伺服器
GitHub Actions介紹及原理
接觸GitHub Actions也有一段時間了,目前此博客正是使用GitHub Action 自動部署到GitHub托管的。今天我將詳細記錄將前端頁面成功部署到伺服器的操作方法,順便分享一些我自己的理解。在有空的時候再進一步完善(下班時間開始😭)。
GitHub Actions官方文檔:GitHub Actions允許您在GitHub存儲庫中自動化、自定義和執行軟件開發工作流。您可以發現、創建並共享操作以執行您喜歡的任何作業(包括CI/CD),並將操作合併到完全自定義的工作流中。
通過文檔可以看出GitHub Action具有強大的代碼管理、運行部署、測試推送等一體化自動發布部署功能,省去了大量的重複性工作。由於通過ssh客戶端連接到伺服器,直接進行前端部署,需要安裝各種依賴,很大程度上降低了伺服器運行效率,且不易對代碼進行修正。
本教程是在《用Nginx Proxy Manager部署靜態網頁》基礎上延伸出的思路,省去了安裝node環境和各種依賴的步驟,直接在GitHub Action中部署前端。每次在本地對後端文件進行修正後,直接將前端發布到伺服器。起到一勞永逸的效果。
GitHub Action成功示图
- 示例分析,以自動部署到GitHub托管為例,分析GitHub Action工作流程如下:
name: luvsia-hugo-blog-autodeploy # 工作流程名稱,自行命名
on:
push: # 什麼時候請求觸發
branches:
- main # 作用分支,這裡是main,也可是master
pull_request:
jobs: # 將工作流文件中運行的所有任務分組在一起
deploy:
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
steps:
- uses: actions/checkout@v2
with: # 如果你安裝主題時用的是git submodule add
submodules: true # 那麼這三行不必註釋掉,這一行填寫 true
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: 'latest' # 獲取最新版本的hugo
extended: true # 如果你使用的不是extended版本的hugo,將true改為false
- name: Build
run: hugo # 使用hugo構建靜態網頁
- name: Deploy to github
uses: peaceiris/actions-gh-pages@v3
if: ${{ github.ref == 'refs/heads/main' }} # 注意填寫main或者master
with:
personal_token: ${{ secrets.PERSONAL_TOKEN }} # 如果secret取了其他名稱,將PERSONAL_TOKEN替換掉
external_repository: ventusoon/LuvSia # 填寫遠程 public 倉庫
publish_dir: ./public
cname: luvsia.com # 填寫自定義域名
- 按照示例分析,可以得出簡單的GitHub Actions步驟圖如下
Action
1️⃣作用條件
時間節點
分支
2️⃣工作任務
運行環境
步驟一
步驟二
步驟 N
直接發布到伺服器/本地/托管頁面
實戰演練
因為要部署到伺服器端,所以要了解連接到伺服器的方式,這裡選擇ssh連接,網上有很多教程也用了sftp連接,都可以。
GitHub Actions部署文件通常以
xxx.yml
命名,路徑為項目根目錄下/.github/workflows/xxx.yml
。在GitHub頁面下編輯
xxx.yml
,可以發現右側的應用商城中有很多特色Actions,因為是ssh連接,在這裡選擇評分較高的ssh-deploy
應用,並使用最新版。
ssh-deploy 應用
配置名稱 | 用途 | 示例 |
---|---|---|
SSH_PRIVATE_KEY | SSH密鑰 | 密鑰應使用PEM格式生成 |
REMOTE_HOST | 遠程主機 | 10.10.10.10 |
REMOTE_USER | 用戶 | root |
REMOTE_PORT | 端口 | 默認22 |
SOURCE | 源,需要部署的內容 | /dist |
TARGET | 對象,要部署的路徑 | /data/docker_data/npm/data/sub.ven2s.cn/ |
ARGS | 傳遞給rsync(同步時)的參數 | -avz --delete |
SSH_CMD_ARGS | 一組ssh參數,它們必須以-o為前綴,用逗號分隔 | -o SomeArgument=no,-o SomeOtherArgument=5 |
EXCLUDE | 要排除的路徑,用逗號分隔 | /dist/, /node_modules/ |
SCRIPT_BEFORE | 在同步之前在主機上運行的腳本 | mkdir -p /data/docker_data/npm/data/sub.ven2s.cn |
SCRIPT_AFTER | 在同步之後在主機上運行的腳本 | reboot |
- 做好以上前期工作,現在可以開始操作了。
在伺服器端配置密鑰
- 在
root
目錄下,輸入以下命令:
ssh-keygen -m PEM -t rsa -b 4096
# 生成密鑰文件,連續按下兩次回車。
# 請注意:您不應該為您生成的私鑰設置密碼(將其保留為空)。因為 rsync ssh(用於部署)不支持將私鑰密碼作為命令行參數輸入。
- 此時,在
/root/.ssh/
下生成了私鑰文件id_dsa
、公鑰文件id_dsa.pub
,根據公鑰文件生成authorized_keys
,並給以上三個文件分別設置權限。
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/authorized_keys
- 此時,客觀上伺服器端的工作就完成了。如果連接中遇到各種錯誤提示,請自行 Google ,這裡就不贅述了。
項目中設置倉庫密鑰
- 說來真是坑,最開始把倉庫密鑰錯填到代碼空間機密中,一直連接不上,我還以為是伺服器的問題,前天甚至弄恍惚了,不小心
rm -rf /
了......
倉庫機密在GitHub項目中設置的位置
- 在伺服器中
cat
密鑰,將所有內容複制到上圖的 SSH_PRIVATE_KEY 中,並填入伺服器IP到 REMOTE_HOST ,填入root
到 REMOTE_USER。(或者直接在yml文件中填入 "root" )
cat ~/.ssh/id_rsa
或者
REMOTE_USER: "root"
發布部署文件到遠端
- 我把自動發布nginx-proxy-manager靜態頁面的文件po在下面,請根據自身的運行環境和依賴進行修改配置即可。
# 當前工作流的名稱
name: sub-web-deploy
on:
push:
branches:
- master
jobs: # 構建的任務,一個工作流有多個構建任務,
build-and-deploy:
runs-on: ubuntu-latest # 在什麼伺服器上面執行這些任務,這裡使用最新版本的ubuntu
steps: # 構建任務的步驟,一個任務可分為多個步驟
# 切換分支
- name: Checkout
uses: actions/checkout@v4
# 步驟2 給當前伺服器安裝node
- name: use node
uses: actions/[email protected]
with:
node-version: 18
cache: "yarn"
# 步驟3 下載項目依賴
- name: install
run: yarn install
# 步驟4 打包node項目
- name: build
run: yarn build
# 步驟5 部署項目到伺服器
- name: ssh deploy
uses: easingthemes/[email protected]
with:
# Private key part of an SSH key pair
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
# Remote host
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
# Remote user
REMOTE_USER: ${{ secrets.REMOTE_USER }}
# Source directory, path relative to `$GITHUB_WORKSPACE` root, eg: `dist/`
SOURCE: "/dist/"
# Script to run on host machine before rsync
SCRIPT_BEFORE: "mkdir -p /data/docker_data/npm/data/sub.ven2s.cn"
# Target directory
TARGET: "/data/docker_data/npm/data/sub.ven2s.cn/"