技術番外篇丨Github Action CI/CD

  • 2021 年 10 月 15 日
  • 筆記

起源

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

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

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

喝水不忘打井人感謝:AlanGrady

正題

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

  1. 你要有一台能上外網的Linux伺服器,並且安裝了docker.
  2. 你要有一個Github倉庫(正兒八經的項目請一定要私有)
  3. 阿里雲鏡像服務(//cr.console.aliyun.com/us-west-1/instance/repositories)
  4. 本次教程使用的項目是我Abp vNext的入門系列大家可以fork一個跟著教程練習(//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 //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的源碼解析文章。