基於Github Actions + Docker + Git 的devops方案實踐教程

為什麼需要Devops

dveops的概念提出已經近十年,各種devops的實踐方案已經陸續在各個開發團隊應用,通過版本控制工具(Git、SVN) + 源程式碼倉庫(Gitee、Github) +CI/CD平台(Jenkins、Github actions、Travis CI…)的devops方案使得開發人員的開發體驗得到極大的提升,即減少了開發和運營的成本又提高了產品品質…

由於個人閱歷不足無法繼續詳細闡述devops的優勢和作用,所以我推薦了一篇blog

devops基礎理念梳理

如何實踐Devops

廢話說那麼多,不如實踐一下見好壞,以Jenkins、Github actions、Travis CI等等CI/CD平台為中心都可以很好的做到持續集成持續部署,在碼雲源程式碼倉庫中我們可以看到如下流行的devops方案

image-20211213123551508

以及在github中集成的Actions

image-20211213123709387

所以我們真正搭建這樣一個流水線平台到底需要使用什麼技術,掌握什麼工具?

我總結如下:

  1. 掌握流行的版本控制工具(Git,SVN)基本使用方法
  2. 依託一個源程式碼倉庫(github、gitee)
  3. 基本的linux運維技術(ssh遠程、docker)
  4. 一個CI/CD平台(Jenkins、Github actions、Travis CI…)

就這麼多,不需要掌握任何編程技巧!

以上每一個技術精通都是不容易的,但是我們只需要任選其一掌握基本方法,能串起來就行。

我根據自己的技術棧設計了這樣一個devops的方案

Untitled (1)

為此我們需要按部就班做一些準備工作

版本控制工具(Git)

學習使用

學習使用方法,這裡我推薦廖雪峰的Git學習網站阮一峰-Git命令清單阮一峰-Git原理

配置環境

  1. 安裝軟體git官網

  2. 檢驗安裝

    git --version
    

    image-20211213131225874

  3. 配置本地用戶資訊

    git config --global user.name "Name"
    git config --global user.email "**.com"
    git config --list
    

    image-20211213131544008

    image-20211213131726959

源程式碼倉庫

這裡我就不贅述了,太簡單了,搜索引擎找一找,如圖所示,我在github上建了一個這樣的倉庫(空倉庫就行,程式碼可以後加)image-20211213132238551

注意,本教程依託了Github Actions這樣一個平台,必需使用Github,所以網路問題需要自己解決

我們準備了如下圖所示目錄結構的一個基於Asp .NET Core 6 的一個圖書管理系統的項目。然後將源程式碼推送到遠程程式碼倉庫如上圖所示。(推送指令就不在詳細描述,掌握了git的基本使用就會明白)

image-20211213161812137

一台配置好環境的雲伺服器

為此我準備了一台4g運行記憶體,8M頻寬的騰訊雲伺服器。作業系統為ubuntu

image-20211213162915469

SSH遠程登錄

你可以使用雲伺服器控制台提供的遠程工具,也可以使用xshell之類的遠程控制工具。為了之後的操作能夠儘可能順利進行,你需要會使用一些基本的linux指令,可以看看這個linux快速上手影片

xshell有免費版,下載安裝後如下新建一個會話

image-20211213164150612

之後按照提示輸入賬戶名和密碼就好

image-20211213163900427

在伺服器上安裝docker

docker技術準備工作

這裡我隨便找了個影片狂勝-docker詳細教程,大致看一下就能對docker有一個了解

一篇部落格為什麼要使用docker

我們知道一個項目要想運行起來是需要運行環境的,為了運行一個java項目我們為伺服器安裝對應版本的Jdk或Jre, 一個.Net應用想要運行起來需要對應版本的.Net FrameWork 或者.Net Core 的SDK,比如我們日常使用的可執行程式qq,weixin等等都是需要運行環境的,只不過windows提前安裝好了各種版本的.Net Framework,使得我們安裝好應用後就能直接使用。又比如在伺服器上安裝相應的資料庫(mysql,sqlserver),管理這些開發環境是相當煩人的,但是當我們使用了docker這樣一個容器化技術後庫,程式碼即環境,可以在任何一台裝有docker的伺服器上運行,不需要配置任何環境。

安裝docker

菜鳥教程-ubuntu安裝docker

使用docker安裝mysql

有了docker我們安裝mysql將變得easy

docker pull mysql

image-20211213170543918

檢查一下我們拉去下來的docker鏡像

docker images

image-20211213170707008

運行

docker run -d --name mysql3306 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=******* mysql

查看一下正在運行的的服務

image-20211213171048914

這樣我們就創建按好了一個伺服器上的資料庫,這樣的資料庫不僅能用於生產環境,用來學習也是不錯的,畢竟在筆記型電腦上裝資料庫會比較占記憶體。

於是我就能在我的項目中配置資料庫連接字元串使用這個資料庫了image-20211213171540367

不管這個項目在哪台主機上啟動,都是可以成功運行的,畢竟資料庫的Ip, 密碼都是固定的。

選擇合適的CI/CD平台

如前文所說,我所用的是github actions,最初我是在Asp .NET Core的官網文檔上了解到的這個技術,自從github被微軟收購後,github actions就一直是微軟推薦CI/CD技術。

github actions官網文檔

想要真正理解這門技術,最好閱讀一下英文版的文檔,在看完「Understanding Github Actions”和」Finding and Customizing actions”這兩欄的介紹後,基本上就可以上手github acitions了

image-20211213172251298

推薦一篇blog,看完後你可以對其有個簡單了解 阮一峰-github actions入門

在本地程式碼倉庫中配置好dockerfile

在我的項目中實現如下

image-20211213173005228

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["BMS.csproj", "./"]
RUN dotnet restore "BMS.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "BMS.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "BMS.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "BMS.dll"]

嘗試使用docker在本地打包構建部署

我們使用docker就可以根據這個文件將項目源碼按照我們想要的方式打包構建好

這裡我們簡單演示一下,進行該測試需要在本地電腦安裝docker,

切換到有dockerfile的項目目錄下使用

docker build .

image-20211213173429247

image-20211213174130158

image-20211213174331904

這個沒有tag的鏡像就是我們剛剛構建的

docker run -d --name bmstest -p 8080:80 7ab686d20640

image-20211213174929024

image-20211213175003600

打開遊覽器檢查一下是否成功運行

image-20211213175139597

成功了!

但是,還不夠方便,雖然我們每次修改完程式碼運行幾個命令就運行好了,別人也可以拿著我們的鏡像去運行程式,但是執行的命令是固定的,我們能不能在修改完程式碼後就自動讓其打包構建部署,事實證明是可以的,人類也是可以在偷懶中進步的。

使用Github Actions自動化打包構建

image-20211213182007308

我們們在項目目錄workflows下建立自己的workfile

image-20211213182422517

name: .NET

env: 
  IMAGE_NAME:  test

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Setup .NET
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: 6.0.x
    - name: Restore dependencies
      run: dotnet restore
    - name: Test
      run: dotnet test --no-build --verbosity normal
    - name: Docker Login
      uses: docker/[email protected]
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}
    - name: Build and Push
      uses: docker/build-push-action@v2
      with: 
        tags: horaoen/app:latest 
        push: true
        context: ./BMS
    - name: deploy
      uses: appleboy/ssh-action@master
      with: 
        host: ${{ secrets.HOST }}
        username: ${{ secrets.HOST_USERNAME }}
        key: ${{ secrets.HOST_SSHKEY }}
        script: |
          docker stop bms-container
          docker rm bms-container
          docker rmi horaoen/app:latest
          docker pull horaoen/app:latest
          docker run -d --name bms-container -p 8080:80 horaoen/app

可以看到這裡的yml文件引用了幾個變數,這些是有關用戶安全的東西不能直接寫在配置文件中,需要在github 的倉庫中設置

image-20211213182841482

添加自己需要的密鑰

image-20211213182952946

image-20211213182911695

workfile詳解

關於上面這個dotnet.yml的github actions的配置文件怎麼寫的需要先了解github actions的基本原理

然後掌握一下幾個Actions的使用

其實這些actions用戶下項目,基本格式是users/repository,是一些別人寫好的腳本,通過重複利用別人寫好的腳本,我們可以很方便的做許多事

actions/checkout@v2

這個是用於將遠程倉庫中的源程式碼拉取到workfile自動化構建腳本運行的伺服器,在我們這裡是github提供的ubutu latest(這在配置文件中寫的有)

actions/setup-dotnet@v1

這個是用於搭建項目的基本環境

docker/[email protected]

docke官方給的antion,用於登錄docker以便我們後續上傳docker鏡像到自己的鏡像倉庫

docker/build-push-action@v2

構建docker鏡像,推送到自己的docker鏡像倉庫,這個context參數是比較難理解的,實際上是相對以遠程程式碼倉庫的根路徑的Dockerfile的路徑image-20211213184619882

在這個aciton的官網文檔中介紹到,dockerfile的文件路徑默認在context/Dockerfile 下,所以這個配置很重要不能配錯。

appleboy/ssh-action@master

在我們成功將docker鏡像推送到鏡像倉庫後,需要ssh連接我們自己要部署項目的伺服器,然後在其上運行一系列docker commond去部署項目。

其它參數一目了然,唯獨這個稍微麻煩,它是我們將要連接到的伺服器的ssh私鑰,在這個action的官網中給出了教程image-20211213185043823

官網文檔

image-20211213185346575

可以照著教程,其實你已經看到這裡就說明具備解決這個問題的能力,詳細步驟可以查一下部落格怎麼配置ssh密鑰。需要注意的是複製盡量用指令去複製,錯一個字元都不行

私鑰一定要把上下分割線也複製上,巨坑!!!

image-20211213185848449

image-20211213185905667

演示效果

image-20211213190350169

image-20211213190411877

image-20211213190549952

查看項目

image-20211213190823418

我們發現有亂碼,這裡正好模擬實際項目中的bug,現在我們修改程式碼修復bug

實際上改一下encoding就好了,然後重新提交程式碼

image-20211213191453683

image-20211213192103688

成功了!!

心得

顯然從結果來看,這很方便,但是學習技術的過程是很痛苦的,如果把學習過程放到比較條件中去是不公平的,學習一次收益很久,但是不做改變就會一直麻煩。

評論區可以留言,我會儘力解答。

Tags: