使用 Gitlab CI/CD 實現自動化發布站點到 IIS


說明

這里先介紹下兩個東西 CI/CDGitLab Runner,當然在此之前你需要對 git 有所了解,關於 git 這里不做說明,可以自行百度。

首先介紹 CI/CD :隨着我們開發方式的轉變,程序的發布變得非常頻繁,而其這些發布操作都是重復的。CI/CD 就是為了使這些操作能變得自動化,那它是怎么實現自動化的呢?其實它做的就是當我們使用 git push(推送)代碼的時候會執行 任務(task) 而這個 任務 里面其實又包含多個 作業(job),如對代碼進行單元測試、部署項目等等,這些 任務作業 在 gitlab 中其實是以一個 .gitlab-ci.yml 文件存在的,這個文件后面會說明。好了我們知道了 CI/CD 是什么(心虛~,你們可以自行百度查看更詳細的說明。),那么到底是誰在執行這些 任務作業 的呢?這就是下面要介紹的 GitLab Runner

GitLab Runner:GitLab Runner 就是用來運行我們定義好的 任務作業 也就是 .gitlab-ci.yml 文件。Runner 分為 Shared Runner(共享型) 和 Specific Runner(專有型),Shared Runner 是所有的項目都能用,但只能由管理員創建,而 Specific Runner(專有型)只能為指定的項目服務。Shared Runner 一般是用在有多個項目的服務器上,Specific Runner 則是單個項目的服務器,或者是你自己的電腦上。

下面列出我本次使用的環境:

操作系統:Windows 10
項目版本:.NET Core 2.2
腳本執行環境:PowerShell 5.1.17763.316
Web服務器:IIS 10.0
Gitlab:使用 gitlab.com (*Gitlab 支持私有化部署 )

項目地址:https://gitlab.com/WigorRunnerTest

Runner

Gitlab CI/CD

首先你需要在 GitLab 上注冊個賬號,這里需要使用你懂的工具上網,因為它使用了谷歌的 reCAPTCHA,如果你是自己部署的 gitlab 將沒有這個問題。如果大家有需要請留下郵箱。

Gitlab 設置中文界面

Gitlab 默認的界面是英文的,只需要點擊頭像行的 Settings,然后點擊 左側導航欄Preferences,之后在滑到最底部找到 Localization 旁邊的 Language 選擇 簡體中文,最后點擊 Save changesF5 刷新頁面即可。

查看設置中文教程

設置好后我們可能更方便的操作 gitlab 了,接着我們需要創建一個項目,這里將使用一個 DotNET Core 項目為例。創建好項目后我們需要將它先 clone 到本地。

下載 Gitlab Runner

在我們定義 任務作業 之前我們需要在我們的服務器或者是電腦上安裝好 Gitlab Runner

官網下載地址:https://docs.gitlab.com/runner/install/

下面是我整理好的下載地址,本次使用的是 Windows amd64

Windows: 下載x86下載amd64

下載好后,找到你下載的目錄,將軟件重命名為 gitlab-runner.exe。只用使用 cmd 進入到該目錄,需要注意的是你需要以 管理員 的方式運行 cmd,否者后面執行命令的時候會報錯。

快捷打開cmd

注冊 Gitlab Runner

接着在命令行中輸入:

gitlab-runner register

這時會出現提示:Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):

它叫你輸入協調器的地址,這個地址是在你 gitlab 項目的 左側導航欄設置 下的 CI/CD 中,找到 Runner 點擊展開,就會看到 專有Runner共享Runner ,這里我們使用 專有Runner 做演示說明。紅色框中的東西是我們后面需要用到的東西。

coordinator URL

好了我們有了 coordinator URL 把它復制下了,粘貼到剛剛的命令中回車。

出現了另外一個提示:Please enter the gitlab-ci token for this runner:,需要你輸入 token ,這個 token 就是你剛剛復制 URL 下面的 注冊令牌。接着它要你輸入這個 Runner 的描述,這個根據自己的情況填。

之后又來一個提示:Please enter the gitlab-ci tags for this runner (comma separated):,需要我們輸入 Runner 的標簽,這里我使用 deploy。

最后一個提示:Please enter the executor: docker, virtualbox, shell, ssh, docker+machine, docker-ssh+machine, kubernetes, docker-ssh, parallels:,需要我們填入腳本的執行環境,這里先填 shell,這時你的 gitlab-runner.exe 下會生成一個 config.toml 文件,里面保存着我們剛剛輸入的信息。

執行過程

需要注意的是這個標簽就是我們后面編寫 .gitlab-ci.yml 里的 job 會用到,它根據 tags 來指派哪些 Runner 會執行該 任務作業

之后我們回到 gitlab 可以看到這里已經有個激活的運行器了,這里的圖標也變成了綠色。如果你這里顯示的不是綠色,那么你刷新下頁面看看,還不行的話那么你需要運行 gitlab-runner restart 命令來重啟 Runner,接着可以使用 gitlab-runner status 查看 Runner 的運行狀態。出現 gitlab-runner: Service is running! 那么表示你的服務已經運行成功了。 再次強調你的命令需要使用 管理員 身份運行。

運行器

將 Shell 改成 PowerShell

上面選擇腳本執行環境的時候我們選了 shell,但是本次我是在 Windows 環境下運行,所以需要將它改為 PowerShell,打開 config.toml 文件,在 [[runners]] 下加入 shell = "powershell" ,然后保存文件即可。
將 Shell 改成 PowerShell

.gitlab-ci.yml 簡單說明

上面已經提過 .gitlab-ci.yml 使用來干什么的了,.gitlab-ci.yml 其實是本次自動化發布的核心,它是放在你 gitlab 上項目的根目錄下。這里將對 .gitlab-ci.yml 該怎么配做一個簡單說明,我只會介紹我用的東西更多的東西你可以查看我下面的「相關文檔」。

首先在項目根目錄下建立一個 .gitlab-ci.yml 文件,代碼如下:

before_script:
  - cd src
stages:
  - test

# job
test:
  stage: test
  # 將會執行的腳本
  script:
    - dotnet restore
    - dotnet build
  # 哪個分支會執行
  only:
    - master
    #runner 注冊時的 tag,這里指會觸發的 runner
  tags:
    - deploy

我們來一個個說明這些東西的作用:

before_script 在整個項目 clone 到 Runner 所處的服務器時會先執行這個里面的腳本,這里我是進入到了 src 目錄,你還可以在這里面做一些包還原的操作。

stages 里放的是將會執行的 job。

test 是做作業(job),這個命名你可以根據自己的情況來。test 就是上面 stages 會執行的 job 的真正配置處。

  1. stage 對應 stages 中的項,如果一個 job 沒有指定 stage,那么這個任務會分配到test stage。

  2. script 就是執行的腳本,構建自動化的核心也就是在此處。作為簡單的演示,我就還原了包和生成項目。

  3. only 是值該 job 會在被哪些分支 push 觸發。

  4. tags 上面在我們注冊時有提到過,這個 tags 對應的是我們注冊 gitlab runner 時所填的 tages,表示的是該 job 會觸發哪些 Runner。

OK,我們此時已經將一個最簡單的 .gitlab-ci.yml 構建好了,在項目根目錄下執行 git commit -am "[init] .gitlab-ci.yml"git push,將配置好的文件 push(推送)到遠端。回到 gitlab 中,我們點擊 CI/CD 可以看到有一個流水線在運行。

job

點進去可以看到運行的日志,可以看到我們 before_scriptscript 中的命令在一條條的執行,當然如果你的腳本出現了錯誤,狀態會是 失敗,你需要檢查你的腳本是否有誤。如果你的狀態一直處於 等待中 那么需要檢查你的 gitlab runner 是否允許正常,以及上面提到的 設置 中的 Runner 是否處於激活狀態(綠色圖標)。

joblog

輸出亂碼問題解決

你可能發現了這里怎么有一些奇怪的字符,這是因為我的操作系統是中文,亂碼了解決辦法是在 before_script 加入 - chcp 65001 腳本。

再次提交代碼,ok 這次的中文信息顯示正確了。
中文信息顯示

變量作用的說明

.gitlab-ci.yml 是存放在我們項目的根目錄下的,如果我們項目使開源的,那么我們將會暴露一些私密信息如token,密鑰,項目發布所處服務器的路徑,這些信息公開可能會使我們的項目存在安全隱患。亦或者我們需要部署多個項目但是它們的 .gitlab-ci.yml 文件十分相似那么我們就可以通過變量控制哪些可變的因素。

那么到底怎么使用變量呢?第一步我們需要先聲明變量,在 gitlab 的項目中找到 設置 下的 CI/CD,可以看到 變量 然后展開,這里就是可以聲明我們需要用到的變量。.gitlab-ci.yml 只需要在腳本需要用到變量的方法使用 $env:變量名 的形式使用即可,需要注意的是:不同的系統使用變量的方法也不一樣,這里我使用是 PowerShell。

變量配置

常用的變量使用方法:

Shell 使用方法
bash/sh $variable
windows batch %variable%
PowerShell $env:variable

關於變量的更多說明可以參考官方的文檔:https://gitlab.com/help/ci/variables/README#variables

自動化部署到 IIS

前面已經介紹了構建一個自動化的流程,有了前面的基礎其實自動化部署到 IIS 也就是編寫的腳本發生了變化。

再開干之前我們需要把我們的思路捋一捋,核心在於怎么通過命令的形式發布一個站點。

  1. 首先需要編譯項目,確保代碼沒有問題
  2. 使用 dotnet publish -c release -r win81-x64 獲取我們需要發布站點的部署文件
  3. IIS 停止運行需要發布的站點
  4. IIS 停止該站點的進程池
  5. 備份原有項目(不是必須,但是最好不要省去該步驟)
  6. 刪除 IIS 上需要發布的站點的原有文件
  7. 復制我們准備好發布的文件(也就是 publish 文件夾)到 IIS 站點下
  8. IIS 啟動進程池
  9. IIS 啟動該站點

下面一步一步已腳本的形式來說明:

  1. 首先確定整體的東西,這里我准備構建兩個 job testdeploy,第一個 job 用於校驗我們的代碼是否正確,第二個是部署的 job。第一個 job 只有兩行命令,還原和編譯。
before_script:
  #中文亂碼問題
  - chcp 65001
  - cd src

# 執行的 job 
stages:
  - test
  - deploy

# 校驗代碼
test:
  stage: test
  # 將會執行的腳本
  script:
    - dotnet restore
    - dotnet build
  # 哪個分支會執行
  only:
    - master
    #runner 注冊時的 tag,這里指會觸發的 runner
  tags:
    - deploy

# 部署
deploy:
  stage: deploy
  # 將會執行的腳本
  script:

  # 哪個分支會執行
  only:
    - master
  #runner 注冊時的 tag,這里指會觸發的 runner
  tags:
    - deploy
  1. 在進行編寫剩下的腳本之前需要定義幾個變量:
    ProjectName:項目名稱,用於 publish 用,如 VS 下一個解決方案可能存在多個項目,這時候就需要知道我們 publish 的項目使哪個。
    WebSiteName:站點名稱,用戶關閉 IIS 站點和 IIS 對應進程池的,如果你的進程池和站點的名稱不一致請在聲明一個變量。
    WebSitePath:站點的路徑,用於備份、刪除原有站點、新的項目復制到該路徑下。

變量配置

定義好這些變量后接着寫我們 deploy 的腳本:
可以看到這里使用了:$env:ProjectName$env:WebSitePath$env:WebSiteName 變量。

# 部署
deploy:
  stage: deploy
  # 將會執行的腳本
  script:

    # 聲明一個變量保存當前時間,用作備份數據文件夾名稱
    - $datetime=Get-Date -Format 'yyyy-MM-dd-HH-mm'
    # 編譯打包項目
    - dotnet publish -c release -r win81-x64
    # 進入編譯好的項目目錄
    - cd $env:ProjectName\bin\Release\netcoreapp2.2\win81-x64\
    # 停止 IIS 對應站點
    - C:\Windows\System32\inetsrv\appcmd.exe stop site $env:WebSiteName
    # 停止進程池
    - C:\Windows\System32\inetsrv\appcmd.exe stop apppool /apppool.name:"$env:WebSiteName"
    # 備份原有項目文件,項目名_當前時間
    - cp "$env:WebSitePath" "$env:WebSitePath$datetime" -Recurse
    # 刪除原有站點
    - del "$env:WebSitePath" -Recurse
    #復制 publish 文件到站點
    - cp "publish" "$env:WebSitePath" -Recurse
    # 啟動進程池
    - C:\Windows\System32\inetsrv\appcmd.exe start apppool /apppool.name:"$env:WebSiteName"
    # 啟動 IIS 站點
    - C:\Windows\System32\inetsrv\appcmd.exe start site $env:WebSiteName
  
  # 哪個分支會執行
  only:
    - master
  #runner 注冊時的 tag,這里指會觸發的 runner
  tags:
    - deploy

到這一步整個自動化發布已經完成了,我們只要 push 代碼到遠端就會自動部署我們的項目到 IIS 中,需要注意的是你必須確保你的 IIS 中已經有這個站點了。

回到 gitlab 中查看 CI/CD 可以看到這次我們的階段有兩個,因為我配置了兩個 作業(job),一個 test一個 deploy。

階段展示圖

點擊每個作業中看看執行的腳本是不是我們定義好的,需要提一下 powershell 腳本如果出錯的話 gitlab-ci 返回的結果還是會顯示成功,錯誤提示還是亂碼的,坑啊。額~目前還找到解決的辦法,如果是 docker 或者 linux 下應該沒有這問題。

log

再看看 IIS 這邊的效果,文件已經自動備份了,站點也正常運行了,一個自動化部署項目到 IIS 站點已經完成了。
文件
站點

模擬項目發布

下面修改代碼然后 push 上去看看,看看我們的網站沒有沒有更新。

完整的 .gitlab-ci.yml

before_script:
  #中文亂碼問題
  - chcp 65001
  - cd src

# 執行的 job 
stages:
  - test
  - deploy

# 校驗代碼
test:
  stage: test
  # 將會執行的腳本
  script:
    - dotnet restore
    - dotnet build
  # 哪個分支會執行
  only:
    - master
    #runner 注冊時的 tag,這里指會觸發的 runner
  tags:
    - deploy

# 部署
deploy:
  stage: deploy
  # 將會執行的腳本
  script:
    # 聲明一個變量保存當前時間,用作備份數據文件夾名稱
    - $datetime=Get-Date -Format 'yyyy-MM-dd-HH-mm'
    # 編譯打包項目
    - dotnet publish -c release -r win81-x64
    # 進入編譯好的項目目錄
    - cd $env:ProjectName\bin\Release\netcoreapp2.2\win81-x64\
    # 停止 IIS 對應站點
    - C:\Windows\System32\inetsrv\appcmd.exe stop site $env:WebSiteName
    # 停止進程池
    - C:\Windows\System32\inetsrv\appcmd.exe stop apppool /apppool.name:"$env:WebSiteName"
    # 備份原有項目文件,項目名_當前時間
    - cp "$env:WebSitePath" "$env:WebSitePath$datetime" -Recurse
    # 刪除原有站點
    - del "$env:WebSitePath" -Recurse
    - cp "publish" "$env:WebSitePath" -Recurse
    # 啟動進程池
    - C:\Windows\System32\inetsrv\appcmd.exe start apppool /apppool.name:"$env:WebSiteName"
    # 啟動 IIS 站點
    - C:\Windows\System32\inetsrv\appcmd.exe start site $env:WebSiteName
  
  # 哪個分支會執行
  only:
    - master
  #runner 注冊時的 tag,這里指會觸發的 runner
  tags:
    - deploy

小結

至此已經實現了 push 時項目自動發布到 IIS 。當然在這個過程中踩了 n 多的坑,總結要細心安裝步驟一步一步認真的走。下一步准備對接釘釘的機器人。實現的效果是當我們項目發布時會自動通知,發布成功后也會自動通知。

相關文獻

《什么是 CI/CD?》:https://linux.cn/article-9926-1.html

《GitLab-CI與GitLab-Runner》: http://www.cnblogs.com/cnundefined/p/7095368.html

《IIS 站點和進程池關閉》:https://www.cnblogs.com/jmaly/p/9860606.html

《Gitlab-CI job 配置文件 .gitlab-ci.yml 配置方式(翻譯)》:https://blog.csdn.net/kunyus/article/details/81390330

powershell論壇:https://www.pstips.net

GitLab Runner 官方文檔:https://docs.gitlab.com/ee/ci/runners/README.html


免責聲明!

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



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