docker+aspnetcore+gogs+jenkins 持續部署


jenkins 是很好的一個CI/CD工具

我們現在用jenkins做個CD 玩玩,畢竟在開發階段,需要頻繁的提交。發布,這樣繁瑣的工作,

如果由人工操作,會很累

 

安裝就不講了。看看我前面的文章

  docker 安裝:https://www.cnblogs.com/nsky/p/10372287.html

  jenkins安裝:https://www.cnblogs.com/nsky/p/13339473.html

  gogs安裝:https://www.cnblogs.com/nsky/p/13339343.html

 

首先我說下我遇到的坑,剛開始我是在阿里雲服務器跑着玩的,環境都搭建好后,

我一構建開始,jenkins容器就掛了,查看logs也沒有exit原因,

剛開始以為是權限的問題,后來又以為是鏡像的原因,我用了jenkins鏡像自己打包

又用了jenkinszh/jenkins-zh,用了jenkins/jinkins,jenkinsci/blueocean 等沒錯都是一構建就掛

后來才發現是配置低了。我的配置是1核1G的。本來就是買來玩玩的。配置低,所以價格才便宜

我之所以不在本地玩,是想更趨向於實戰,

不過我還有一台搬*工的是2H1G的。

 

既然有2台電腦。所以,就完成2個目標

1:本地構建(jenkins和gogs都在同一台服務器)

2:遠程觸發構建(jenkins和gogs不在同一台服務器)

 

那么阿里雲服務器叫A,搬*工服務器叫B

服務器名稱  IP 安裝軟件
阿里雲服務器(A) 39.105.144.51 gogs
搬*工(B) 104.128.92.44 jenkins,gogs

 

 

本地構建(jenkins和gogs都在同一台服務器)

這里是操作服務器B

機制:

就是當用戶提交代碼到gogs上,gogs通知jenkins,構造部署。所以這里用到了web鈎子:webhook

其實jenkins 是把git代碼拉取到了本地,下面可以演示出來

 

1:創建一個core程序,上傳到gogs上

 

 

 

core 項目的Dockerfile

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
ENV TZ Asia/Shanghai

#EXPOSE 443 FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build WORKDIR /src COPY . . RUN dotnet restore RUN dotnet build FROM build AS publish RUN dotnet publish "mytest.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app # 從發布階段的中拷貝編譯結果到當前鏡像中 COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "mytest.dll"]

 

 

 

2:jenkins 安裝gogs插件

在系統管理=》插件管理=》可選插件=》搜索gogs

 

 

 

安裝后,開始配置,新建任務

 

 

 

 

幾個重點配置

 

 

 

Repository URL :填寫你的倉庫地址

Credentials:選擇你的憑據

如果你沒有添加全局憑據,這里下拉是沒有值的

1:可以在用戶憑據中添加

2:可以直接單擊這個添加,跳轉到添加憑據界面

 

 

 輸入用戶名密碼。就是我們工作中拉取git的用戶名和密碼,其他的不填寫,單擊添加后,選擇剛添加的

 

 

 提示成功了

 

 

 

這里指定分支,我這是測試。默認就是master

 

 

 

 

連接上了gogs。那么就是構建部署了。構建肯定要執行命令是吧。那么這里就要添加構建部署的命令

 

 

 

 輸入命令:這命令我有參考網絡修改,有很多提示的文字,自己修改,這不是重點

echo "獲取當前容器是否存在-----------------------------------------------------------------"
containerps=$(docker ps -f name=mymvc -q)
containerstop=$(docker ps -a -f name=mymvc -q)
for alpha in "$containerps";do
    if [ "$alpha" = "" ];then
    echo "檢查是否存在停止的容器-------------------------------------------------"
        for alpha1 in "$containerstop";do
          if [ "$alpha1" = "" ];then
          echo "不存指定容器-----------------------------------"
          else
          echo "存在停止了的 然后直接刪除-----------開始------------------"
          docker rm $alpha1
          echo "存在停止了的 然后直接刪除-----------完成------------------"
        fi
       done
    else
    echo "存在-停止運行 然后刪除----------------------開始-----------------"
    docker stop $alpha
    docker rm $alpha
     echo "存在-停止運行 然后刪除---------------------完成------------------"
    fi
done



echo "獲取當前鏡像是否存在-----------------------------------------------------------------"
dockerlist=$(docker images mvcimage:latest -q)
for alpha2 in "$dockerlist";do
  if [ "$alpha2" = "" ];then
     echo "不存在指定鏡像-------------------------------------------------" 
  else
       echo "存在當前指定的鏡像 刪除鏡像--------------開始-----------------------------------"
      docker rmi $alpha2
     echo "存在當前指定的鏡像 刪除鏡像--------------完成-----------------------------------"
  fi
done
echo "開始輸入工作目錄-----------------------------------------------------------------"
echo $WORKSPACE
echo "轉到項目工程目錄-----------------------------------------------------------------"
cd $WORKSPACE/myproject
echo "構建Docker鏡像-------------------------------開始----------------------------------"
docker build -t mvcimage .
echo "構建Docker鏡像-------------------------------完成----------------------------------"
echo "運行Docker容器-------------------------------------開始----------------------------"
docker run  --name=mymvc -p 8802:80 -d mvcimage

 

我們在build鏡像的過程中,可能會產生一些臨時的不具有名稱也沒有作用的鏡像他們的名稱一般都是<none>,我們可以執行下面的命令將其清除掉:

所以在腳本最后加條命令

docker rmi $(docker images -f "dangling=true" -q)

 

noneImage = docker rmi $(docker images -f "dangling=true" -q)

if [ ! -n  "$noneImage"]; then

else 

docker rmi $(docker images -f "dangling=true" -q
fi

精簡版本
docker stop Web
docker rm Web
echo $WORKSPACE
cd $WORKSPACE/project
docker build -t myimages .
docker run  --name=Web -p 8802:80 -d myimages
docker rmi $(docker images -f "dangling=true" -q)

 

 

 

 

 

 然后單擊保存即可

jenkins是把git上的代碼拉取到了workspace文件夾下。

所以你會看到命令中有cd  $WORKSPACE

 

 

 

 

可以看看文件具體位置。在jenkins_home/workspace下有拉取的項目

 

 

 /docker/jenkins_home/workspace 這個目錄,是你掛載的目錄

 

 

 進去就可以看到。里面有源代碼,

 

 

 

如果想測試,看是否配置正確。可以單擊立即構建,我這里就不演示了

 

 

 

 

 

jenkins配置完成了。然后去gogs配置

 

 

 

 

 

 

 

 

 

 

 

然后配置如下:推送地址中的參數,job=myproject,是必須跟我們在jenkins創建任務的名稱匹配才行

推送事件,根據自己的需求來。然后單擊添加

http://104.128.92.44:8080/gogs-webhook/?job=myproject

 

 

 

 

 

 

 

 

上面那個,是我之前測試的。可以忽略,然后單擊進去,可以測試推送下

 

 

 測試成功

 

 

 

回到jenkins面板,看看構建記錄

 

 

 

進去,看控制台輸出

 

 

 看容器也已經啟動,端口是8802,嘗試訪問一下

 

 

訪問成功:

 

 

 

 

 

好了。接下來,打開項目,修改下文件,提交

 

 

 

 

 

 

 

至此,這樣在本地構建部署就完成了,

 

 

遠程觸發構建(jenkins和gogs不在同一台服務器)

說明:

 阿里雲服務器(A)上安裝了gogs

搬*工服務器上(B)上安裝了jenkins

 

當有人提交代碼給gogs,就會觸發jenkins

所以:

遠程觸發原理就是:

 A觸發B。告訴B。有人提交代碼,你需要觸發A構建代碼,

B會把本地的一個命令文件上傳到A,然后在A上執行這個命令,完成部署

那么要保證A上的代碼必須是最新的,所以在A上必定需要git操作,

當然,B不一定要上傳文件到A。可以直接觸發A上某個腳本,下面會提到

 

現在阿里雲服務器上的gogs是沒有任何倉庫的

 

把上面測試的項目添加到gogs上

 

 

 

 

在A上安裝git

yum install  -y git

1.配置一個用於提交代碼的用戶,輸入命令:

git config --global user.name "Your Name"

2.配置一個用戶郵箱,輸入命令:

git config --global user.email "email@example.com"

3.生成公鑰和私鑰,輸入命令后一路回車即可

ssh-keygen -t rsa -C "youremail@example.com"

公鑰路徑,待會會用到

 

 

 

進入gogs,倉庫設置=》管理部署密鑰

 

 

 

 

把密碼添加進去保存

 

 

 

在服務器A指定一個目錄,拉取代碼

 

 

 

一段小插曲,如果clone的時候出現

 

 

 用OpenSSH的人都知ssh會把你每個你訪問過計算機的公鑰(public key)都記錄在~/.ssh/known_hosts。當

下次訪問相同計算機時,OpenSSH會核對公鑰。如果公鑰不同,OpenSSH會發出警告,

如果我們重新安裝系統,其公鑰信息還在,連接會出現如上截圖情況

網絡收集:

方法一:

rm -rf ~/.ssh/known_hosts

++++++++++++++++++

優點:干凈利索

缺點:把其他正確的公鑰信息也刪除,下次鏈接要全部重新經過認證

 

方法二:

vi ~/.ssh/known_hosts

刪除對應ip的相關rsa信息(本例可知刪除53行信息即可)

++++++++++++++++++

優點:其他正確的公鑰信息保留

缺點:還要vi,還要找到對應信息,稍微優點繁瑣

 

方法三:

清除舊的公鑰信息

ssh-keygen -R 192.168.0.100

++++++++++++++++++

優點:快、穩、狠

缺點:沒有缺點

 

這樣的git算是弄好了。然后去jenkins上配置任務。

遠程觸發,需要安裝插件:Publish Over SSH

 

 

 

安裝后。進入系統配置

 

 

這里要配置被連接電腦的用戶名和密碼,

現在是B連接A。所以這里配置A服務器的地址

 

 Passphrase:登錄電腦的密碼

SSH Servers:服務器的配置

  Name:名稱(自定義)

  Hostname:服務器地址

  Username:用戶名

  Remote Directory:默認遠程服務器的地址

 

 

 

 

這里單獨創建個任務叫:remote

既然是遠程觸發,源代碼這里就不用設置了

 

 

 

 

 

 

 

 

 

 

 

Transfers:

  Source files:源文件地址,地址的目錄是相對於jenkins workspace的目錄,如果只需要執行命令不需要傳輸文件的時候,此處可以為空

     我這里是上傳文件,a.sh,那么在workspace會有個對應的任務名稱的文件夾 remote

     所以全路徑是:jenkins_home/workspace/remote/a.sh

 

  Remove prefix:去除的文件地址。在Source files輸入框中填入的地址,會默認在服務器下創建相同的文件夾,所以需要將我們不需要的文件夾在這里剔除掉

   比如:

    Source files 填寫的是 u/a.sh,Remove prefix 為空,那么就會在是這樣 /root/u/a.sh

如果Remove prefix 填寫u 就是剔除u文件夾,那么在A服務器上就是 /root/a.sh

 

  Remote directory:遠程服務器接收文件的地址,這里配置的 就是在 根目錄 下

  Exec command:文件傳輸任務執行完畢后,在遠程服務器上執行的命令,要執行的命令,

文件在根目錄下,那么全路徑就是 /root/a.sh

 

a.sh輸入腳本,其實就2句重點

/root/project/mytest/mytest:是我服務器拉取git的路徑

sh publish.sh 是執行腳本

那么publish.sh放什么腳本命令呢?

就是上面測試過的打包命令

 

 那么在/root/project/mytest/mytest 中創建一個publish.sh

 

 幾個重點,先切目錄,git下

然后在切到Dockerfile 目錄下。如果不想切。那么得改打包的命令,指定Dockerfile目錄

docker build  -f  /root/project/mytest/mytest/Dockerfile  -t mvcimage /root/project/mytest/mytest

最后別忘了在A服務上gogs配置weghook

http://104.128.92.44:8080/gogs-webhook/?job=remote

然后自己測試,我就不演示了

 

當然。你這里的jenkins遠程觸發,也可以直接執行服務器A上的腳本,不一定要上傳一個腳本

總得來說,就研究和嘗試了這么多,

哎,寫博客太費時了。以后要少寫。。。。。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM