目的
通過GitHub的Actions來(白嫖)部署.Net服務到阿里云服務器。
環境準備
需要一個阿里云服務器并且該服務器還安裝了docker環境,如果環境安裝不清楚可以查看之前的文章。
創建鏡像倉庫
在阿里云的容器鏡像服務中,創建一個鏡像倉庫用來存儲我們測試的鏡像,這里我提前創建倉庫為myexample,地址為registry.cn-hangzhou.aliyuncs.com/zrng/myexample。
準備項目文件
本文主要討論GitHub的Action功能,所以項目文件直接使用之前示例代碼,在Github創建倉庫my-example,該倉庫的代碼使用之前的代碼(倉庫地址為:https://gitee.com/AZRNG/my-example)
隱私信息配置
在指定的倉庫中,選擇Settings=>Secrets=>Actions

點擊右上的新建就可以創建想要保存的隱私配置信息

這里我保存了一下鏡像倉庫的賬號密碼等信息。

倉庫腳本配置
在倉庫的根目錄新建工作流文件.github/workflows/dotnet.yml(也可以在Actions選項卡中新建),我們將每次提交的項目生成測試鏡像,在dotnet.yml中寫下面內容
#?工作流名稱
name:?Dockeron:push:?#?推送的時候觸發branches:?[?"main"?]?#?推送的分支#?Publish?semver?tags?as?releases.tags:?[?'v*.*.*'?]pull_request:branches:?[?"main"?]env:#?倉庫地址REGISTRY:?registry.cn-hangzhou.aliyuncs.comIMAGE_NAME:?zrng/myexampleIMAGE_TAG:?latestjobs:build:runs-on:?ubuntu-latestpermissions:contents:?readpackages:?write#?This?is?used?to?complete?the?identity?challenge#?with?sigstore/fulcio?when?running?outside?of?PRs.id-token:?writesteps:#?將遠程倉庫中的源代碼領取到workfile自動化構建腳本運行的服務器-?name:?Checkout?repositoryuses:?actions/checkout@v3?#?Login?against?a?Docker?registry?except?on?PR#?https://github.com/docker/login-action-?name:?login?to?${{?env.REGISTRY?}}if:?github.event_name?!=?'pull_request'uses:?docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c?#?用于登錄docker以便我們后續上傳鏡像到自己的鏡像倉庫with:registry:?${{?env.REGISTRY?}}username:?${{?secrets.USERMAME?}}?#?鏡像倉庫用戶名password:?${{?secrets.PASSWORD?}}?#?鏡像倉庫密碼#?生成和推送鏡像??阿里云鏡像倉庫推送有問題#?#?https://github.com/docker/build-push-action#?-?name:?Build?and?push?Docker?image#???id:?build-and-push?#?構建docker鏡像,推送到自己的docker鏡像倉庫#???uses:?docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a#???with:#?????registry:?${{?env.REGISTRY?}}#?????username:?${{?secrets.USERMAME?}}?#?鏡像倉庫用戶名#?????password:?${{?secrets.PASSWORD?}}?#?鏡像倉庫密碼#?????push:?${{?github.event_name?!=?'pull_request'?}}#?????tags:?${{env.IMAGE_NAME}}:${{env.IMAGE_TAG}}.${{?github.run_id?}}.${{?github.run_number?}}?#動態變量鏡像TAG?使用github運行job和jobid設置tag#?????context:?.?#?相對以遠程倉庫根路徑的dockerfile的路徑#?????file:?./NetByDocker/Dockerfile?#?指定Dockerfile-?name:?Build?the?Docker?imagerun:?|docker?version#?登錄阿里云鏡像倉庫docker?login?--username=${{?secrets.USERMAME?}}?--password=${{?secrets.PASSWORD?}}?registry.cn-hangzhou.aliyuncs.com#?使用Dockerfile構建鏡像??${{env.IMAGE_TAG}}.${{?github.run_id?}}.${{?github.run_number?}}docker?build?.?--file?NetByDocker/Dockerfile?--tag?registry.cn-hangzhou.aliyuncs.com/zrng/myexample:${{env.IMAGE_TAG}}?--tag?registry.cn-hangzhou.aliyuncs.com/zrng/myexample:${{?github.run_number?}}#?推送鏡像到鏡像倉庫docker?push?${{?env.REGISTRY?}}/${{?env.IMAGE_NAME?}}:${{env.IMAGE_TAG}}docker?push?${{?env.REGISTRY?}}/${{?env.IMAGE_NAME?}}:${{?github.run_number?}}#?列出所有鏡像????-?name:?Docker?Images?Lst?run:?docker?images
本來在推送鏡像的時候我們可以直接build-and-push來推送,但是推送到阿里云倉庫有問題,我百度說是阿里云倉庫必須寫前面鏡像地址等信息,所以沒成功,所以換用其他方式來實現
上文中涉及的dockerfile文件內容如下
FROM?mcr.microsoft.com/dotnet/aspnet:6.0?AS?base
WORKDIR?/app
EXPOSE?80FROM?mcr.microsoft.com/dotnet/sdk:6.0?AS?build
WORKDIR?/src
COPY?["NetByDocker/NetByDocker.csproj",?"NetByDocker/"]
RUN?dotnet?restore?"NetByDocker/NetByDocker.csproj"??#?還原項目的Nuget包
COPY?.?.
WORKDIR?"/src/NetByDocker"
RUN?dotnet?build?"NetByDocker.csproj"?-c?Release?-o?/app/build?#?在發布模式下生成項目。?生成工件將寫入中間映像的?app/build/?目錄。FROM?build?AS?publish
RUN?dotnet?publish?"NetByDocker.csproj"?-c?Release?-o?/app/publish?#?在發布模式下發布項目。?已發布的捆綁將寫入最終映像的?app/publish/?目錄。FROM?base?AS?final
WORKDIR?/app
COPY?--from=publish?/app/publish?.
ENTRYPOINT?["dotnet",?"NetByDocker.dll"]?#?啟動
在我們提交代碼并推送中可以去github的Actions選項卡中查看

因為一些笨笨的操作,錯誤了好多次

然后再去阿里云鏡像倉庫查看是否有我們推送上去的鏡像

已經存在,說明我們生成鏡像并推送的步驟成功了,也可以通過以下命令拉取到
docker?pull?registry.cn-hangzhou.aliyuncs.com/zrng/myexample:latest
部署鏡像
我們需要讓推送成功后,在我們的阿里云服務器上拉取鏡像并啟動,那么先增加服務器的地址、賬號、密碼、端口等變量

再修改dotnet.yml文件,在最后追加內容
#?列出所有鏡像????
-?name:?Docker?Images?Lst?
run:?docker?images-?name:?executing?remote?ssh?commands?using?password
uses:?appleboy/ssh-action@master
with:host:?${{?secrets.SERVERHOST?}}username:?${{?secrets.SERVERUSERNAME?}}password:?${{?secrets.SERVERPASSWORD?}}port:?${{?secrets.SERVERPORT?}}script:?docker?run?--name?netsample?-d?-p?8002:80?registry.cn-hangzhou.aliyuncs.com/zrng/myexample
我本來是按照上面這方案走的,結果還得考慮到停止并刪除容器,以及刪除鏡像拉取最新的鏡像,所以我索性直接使用docker-compose去處理了,我在服務器的/root/net目錄,放了一個docker-compose文件,內容如下
version:?'3.4'services:?netsample:container_name:?netsampleimage:?registry.cn-hangzhou.aliyuncs.com/zrng/myexamplerestart:?alwaysenvironment:?-?ASPNETCORE_ENVIRONMENT=Productionnetworks:?-?my-bridgeports:?-?"8002:80"networks:?my-bridge:driver:?bridge
然后在dotnet.yml文件后追加
-?name:?executing?remote?ssh?commands?using?passworduses:?appleboy/ssh-action@masterwith:host:?${{?secrets.SERVERHOST?}}username:?${{?secrets.SERVERUSERNAME?}}password:?${{?secrets.SERVERPASSWORD?}}port:?${{?secrets.SERVERPORT?}}script:?cd?/root/net;docker-compose?pull?&&?docker-compose??up?-d;
然后我提交新增加的代碼,等工作流跑結束后

訪問我們項目的swagger(http://IP:8002/swagger/index.html)頁面(前提是阿里云服務器的端口安全組已經設置),既可以看到下面的效果

登錄服務器后查看鏡像版本,也是我們剛剛推送的鏡像。
總結
本文完整介紹了如何使用Github Actions做CI&CD,將ASP.NET Core 6.0 程序的main分支打包并部署到阿里云Linux服務器。
如果想在每次dev提交代碼后自動生成服務(不再推送鏡像倉庫),那么可以稍稍修改上面的腳本使用appleboy/ssh-action@master進入某一個目錄(提前拉取好項目的目錄),然后構建鏡像生成容器。
資料
本文完整代碼可以查看倉庫:https://gitee.com/AZRNG/my-example
完整的dotnet.yaml文件可以查看:https://gitee.com/AZRNG/my-example/blob/master/.github/workflows/dotnet.yml