技術番外篇丨Github Action CI/CD

初久的私房菜發表於2021-10-15

起源

看到.Net群裡再聊CI/CD,我就這裡分享一下我目前自己一些小東西的做法,我目前在Github有一個自己私有的組織,裡面存放了我的部分商業化專案,早期我採用Jenkins用Webhooks進行釋出部署,
Jenkins我用起來太大。很多功能用不到而且還吃我伺服器佔用(ps:主要是高效能伺服器太貴),抱著解決問題和節約成本的思路我發現了Github Actions。

官方說明:在 GitHub Actions 的倉庫中自動化、自定義和執行軟體開發工作流程。 您可以發現、建立和共享操作以執行您喜歡的任何作業(包括 CI/CD),並將操作合併到完全自定義的工作流程中。

官方教程地址:https://docs.github.com/cn/actions

喝水不忘打井人感謝:AlanGrady

正題

首先你要學習此教程你需要下面準備:

  1. 你要有一臺能上外網的Linux伺服器,並且安裝了docker.
  2. 你要有一個Github倉庫(正兒八經的專案請一定要私有)
  3. 阿里雲映象服務(https://cr.console.aliyun.com/us-west-1/instance/repositories)
  4. 本次教程使用的專案是我Abp vNext的入門系列大家可以fork一個跟著教程練習(https://github.com/BaseCoreVueProject/ABPvNext.Blog.Core)

阿里雲配置

  • 首先我們區阿里雲建立一個容器倉庫,這裡要注意選擇的地區是美國,別選國內因為會出現連線超時。

建立容器倉庫1

建立容器倉庫2

建立容器倉庫3

  • 建立好之後注意下面2個位置的連線一會有用

配置服務

配置引數

開啟Github你fork的倉庫地址(去自己的倉庫下),建立配置引數(不要擔心Secrets會被別人知道這是絕對安全的)

配置服務

DOCKER_REPOSITORY: 映象倉庫地址,也就是上一個步驟複製到的公網地址

DOCKER_USERNAME:登入阿里雲的賬號

DOCKER_PASSWORD: 登入阿里雲的密碼

HOST:部署專案的伺服器ip

HOST_PORT:伺服器ssh埠號(預設是22)

HOST_USERNAME:伺服器登入使用者名稱

HOST_PASSWORD: 登入伺服器的密碼

DockerFile

在目錄ABPvNext.Blog.Core\aspnet-core下面的Dockerfile檔案,這裡我採用的是本地編譯上傳映象,你也可以用傳統的那種

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base

WORKDIR /app
EXPOSE 80
EXPOSE 443
COPY . .
ENTRYPOINT ["dotnet", "ShunHang.Mrt.HttpApi.Host.dll"]

建立工作流

在github倉庫皮膚,點選建立工作流

配置服務

下面內容中有一個配置registry.us-west-1.aliyuncs.com這個是我們在阿里雲建立的映象地區有關,如果你和我不一樣注意替換掉。整體指令碼總結就分為2部分,一部分是將程式碼編譯打包成映象並上傳,一部分通過ssh連線伺服器pull映象並刪除舊的啟動新的。


name: Docker Image Core CI/CD

on:
  push:
    branches: [main]  # 在main分支有push操作的時候自動部署
env:
  IMAGE_NAME: ${{ secrets.DOCKER_REPOSITORY }} # 映象名稱
  IMAGE_NAME_TAG: ${{ secrets.DOCKER_REPOSITORY }}:v${{ github.run_id }}.${{ github.run_number }} # 映象名稱:TAG名稱(這裡我很想實現自動1.1.1,1.1.2這種奈何我不會)


jobs:
  build-net-core: # 打包上傳映象
    runs-on: ubuntu-latest  # 依賴的環境 
    steps:
      - uses: actions/checkout@v2
      - name: Build .Net Core
        uses: actions/setup-dotnet@v1
        with:
          dotnet-version: 5.0.x
      - name: dotnet restore  
        run: dotnet restore ./aspnet-core/src/Bcvp.Blog.Core.HttpApi.Host/Bcvp.Blog.Core.HttpApi.Host.csproj
      - name: dotnet publish # 編譯專案
        run: dotnet publish ./aspnet-core/src/Bcvp.Blog.Core.HttpApi.Host/Bcvp.Blog.Core.HttpApi.Host.csproj --configuration -c Release --no-restore -o ./aspnet-core/app
      - name: Docker Image
        run: ls
      - name: Copy DockerFile
        run: cp ./aspnet-core/Dockerfile ./aspnet-core/app
      - name: Login to registry
        uses: docker/login-action@v1
        with: # 登入阿里雲映象伺服器
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
          registry: registry.us-west-1.aliyuncs.com
      - name: Build Image # 打包docker映象
        run: docker build -t ${{ env.IMAGE_NAME_TAG }} ./aspnet-core/app
      - name: Push Image # 推送映象
        run: docker push ${{ env.IMAGE_NAME_TAG }}

  pull-docker:  # docker部署
    needs: [build-net-core]
    name: Pull Docker
    runs-on: ubuntu-latest
    steps:
      - name: Deploy
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }} # 伺服器ip
          username: ${{ secrets.HOST_USERNAME }} # 伺服器登入使用者名稱
          password: ${{ secrets.HOST_PASSWORD }} # 伺服器登入密碼
          port: ${{ secrets.HOST_PORT }} # 伺服器ssh埠
          script: |
            docker stop $(docker ps -a | grep ${{ env.IMAGE_NAME }} |  awk '{print $1}')
            docker rm -f $(docker ps -a | grep ${{ env.IMAGE_NAME }} |  awk '{print $1}')
            docker rmi -f $(docker images | grep ${{ env.IMAGE_NAME }} | awk '{print $3}')
            docker login --username=${{ secrets.DOCKER_USERNAME }} --password ${{ secrets.DOCKER_PASSWORD }} registry.cn-hangzhou.aliyuncs.com
            docker pull ${{ env.IMAGE_NAME_TAG }}
            docker run -d -p 8080:80  ${{ env.IMAGE_NAME_TAG }}


後面只要有程式碼push倒main分支都會自動觸發該流程,進行自動部署,我們可以在Actions中檢視我們的記錄,如果出錯了也是非常容易排查。

配置服務

配置服務

效果

效果

結語

開發過程中一定要學會看日誌,自己排查錯誤,我在上面教程中故意留了一個坑給各位,歡迎大佬評論補坑哈哈哈哈。

學習更多使用技巧請參閱官方文件教程,最後還是感謝AlanGrady的指導。

歡迎各位讀者關注我的部落格,下週開始我會每1-2周更新一篇vNext的原始碼解析文章。

相關文章