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

說明

這裏先介紹下兩個東西 CI/CDGitLab Runner,固然在此以前你須要對 git 有所瞭解,關於 git 這裏不作說明,能夠自行百度。html

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

GitLab Runner:GitLab Runner 就是用來運行咱們定義好的 任務做業 也就是 .gitlab-ci.yml 文件。Runner 分爲 Shared Runner(共享型) 和 Specific Runner(專有型),Shared Runner 是全部的項目都能用,但只能由管理員建立,而 Specific Runner(專有型)只能爲指定的項目服務。Shared Runner 通常是用在有多個項目的服務器上,Specific Runner 則是單個項目的服務器,或者是你本身的電腦上。git

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

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

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

Runner

Gitlab CI/CD

首先你須要在 GitLab 上註冊個帳號,這裏須要使用你懂的工具上網,由於它使用了谷歌的 reCAPTCHA,若是你是本身部署的 gitlab 將沒有這個問題。若是你們有須要請留下郵箱。安全

Gitlab 設置中文界面

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

查看設置中文教程服務器

設置好後咱們可能更方便的操做 gitlab 了,接着咱們須要建立一個項目,這裏將使用一個 DotNET Core 項目爲例。建立好項目後咱們須要將它先 clone 到本地。app

下載 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 站點和進程池關閉》:http://www.javashuo.com/article/p-fdeajjtb-dn.html

《Gitlab-CI job 配置文件 .gitlab-ci.yml 配置方式(翻譯)》:http://www.javashuo.com/article/p-hefxoaqh-g.html

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

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

相關文章
相關標籤/搜索