Mark Ku's Blog
在 ChatGPT 開啟在 Claude 開啟

使用免費 GitLab Pipeline 搭配地端 GitLab Runner,可自動建置 Docker Image 並手動部署,整合 Telegram 與 Line Bot 推送部署通知,解決小團隊手動部署的痛點。

輕量化且免費,適用小團隊的 CICD - 使用 Gitlab Pipeline 及 地端 Gitlab Runner

痛點

一般來說在軟體交付的過程中,開發的環境可能會有
1.開發環境( DEV )
2.測試環境 ( QAT )
3.使用者測試環境( UAT )
4.生產環境 ( PROD )

當專案越來越多時,多個環境,越複雜時,過去的手工佈署應用程式,就可能是件麻煩事,且人工佈署很有可能因不小心,造成環境部署錯誤的問題,那麼為了解決這個問題及節省時間,而需要導入 CICD 工具,達到自動建置及自動佈署

CICD 解決的問題

  1. 解決現有應用有多個分支或多個環境,導致互相衝突。
  2. 降低手動佈版錯誤及失敗、縮短復原時間。
  3. 讓開發人員專注開發。
  4. 改善團隊溝通與協作效率。

何謂 CICD

在那之前,我們先了解什麼是 CICD

在軟體工程中,CI/CD或CICD通常指的是持續集成和持續交付或持續部署的組合實踐。CI/CD通過在應用程式的構建、測試和部署中實施自動化,在開發和運營團隊之間架起了橋樑。 現代DevOps實踐涉及軟體應用程式在整個開發生命周期內的持續開發、持續測試、持續集成、持續部署和持續監控。 (維基百科)

我的 CICD 架構

1.將配置好 Docker 的NET CORE 專案託管到 Gitlab

2.在本地端機器,建置 Gitlab Runner,去建置及佈署應用程式

預期佈版流程

Gitlab手動佈版流程圖
Gitlab手動佈版流程圖

1. Build Stage

Git Commit > Trigger build stage> Build docker image using powershell

2. Deploy Stage

Manual deploy > Trigger deploy stage > Notify User "Deployment Start" > Deploy docker image to container server > Notify User "Deploy end”

開始動手作

1. 首先,必須事先準備

  • 必需要將你的專案託管到 Gitlab ,並設配置好 DockerFile
  • 並將此專案配置 DockerFile (可參考先前的文章)

2. 接著我們進入 Gitlab 後台 > Settings > CI/CD

GitLab專案頁面Settings選單中的CI/CD
GitLab專案頁面Settings選單中的CI/CD

3. 接著找到 Auto DevOps > Expand > 勾選 Continuous deployment to production > Save changes

Gitlab CI/CD設定,Auto DevOps勾選持續部署到生產
Gitlab CI/CD設定,Auto DevOps勾選持續部署到生產

4. 在下面,我們可以 Runners > Expand > 關閉 Shared Runner,並複製 Gitlab CI url 及 token 起來,給地端的 Runner 註冊。

GitLab Runner 設定介面顯示 CI URL 與
GitLab Runner 設定介面顯示 CI URL 與

5. 安裝 gitlab-runner

choco install gitlab-runner
gitlab-runner --version  // 測試版本

P.S. choco 使用教學 GitLab CI/CD 設定頁面顯示 Runner 註冊令牌

6. 註冊 gitlab-runner

gitlab-runner register
PowerShell 終端機顯示 GitLab Runner 註冊成功
PowerShell 終端機顯示 GitLab Runner 註冊成功

7. 啟動 runner

gitlab-runner run

8. 當 Runner 起動後,此時 Gitlab 後台設定就會發現多了一個 Active 的 Runner,可以使用

GitLab 後台 CI/CD Runner 列表顯示已啟動的
GitLab 後台 CI/CD Runner 列表顯示已啟動的

9. gitlab-ci.yml 是 gitlab piplines 設定檔,專案根目錄加入 .gitlab-ci.yml 檔案,則符合條件就會執行相關的 stages 的指令。

stages:
  - build       
  - deploy
  
build:
  stage: build
  script:    
    - ./build.ps1 # build docker image
  only:
    - main    
    
deploy:
  stage: deploy
  script:
    - ./tg-notify.ps1 "deploy start" # telegram bot 通知部署開始
    - ./linebot-notify.ps1 "deploy start" # line bot 通知部署開始
    - ./deploy.ps1 # deploy docker image to container
    - ./tg-notify.ps1 "deploy end" # telegram bot 通知部署結束
    - ./linebot-notify.ps1 "deploy end" # line bot 通知部署結束
  when: manual    
    
default: 
  interruptible: true # 新的流水線工作建立時,目前的這工作是否繼續執行(預設為 false)
  tags:
  - test

10.在專案根目錄,撰寫相關的 powershell - Telegram 通知( tg-notify.ps1 )

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$botToken = 'your token'
$chatID = 'your chatId'
$messageText = $args[0]

$telegramURI = ("https://api.telegram.org/bot" + $botToken + "/sendMessage")
$telegramJson = ConvertTo-Json -Compress @{chat_id = $chatID; text=$messageText}
$telegramResponse = Invoke-RestMethod -Uri $telegramURI -Method Post -ContentType 'application/json;charset=utf-8' -Body $telegramJson

11.在專案根目錄,撰寫 powershell - line bot通知( linebot-notify.ps1 )

$token = your token
$toUserId = linebotUserid
$Header = @{
         'Authorization' = 'Bearer $token'
}

$postParams =  @"
{
     "to": "$toUserId",   
     "messages": [
         {           
             "text": "$args",
             "type": "text"
         }
     ]
    
}
"@

Invoke-WebRequest -Uri https://api.line.me/v2/bot/message/push -Method POST -ContentType 'application/json' -Headers $Header -Body $postParams

12.在專案根目錄,撰寫 powershell 建置 達成建置 Docker Image ( build.ps1 )

$containerUrl = "tcp://192.168.50.52:2376"
$imageName = "shopcart"
$dockerfile = "./Comma.Web/Dockerfile"
$outputPath = "./"
$imageFilePath = $outputPath + $imageName
$port="8888:80"

# 本地建置映像檔
docker build -t $imageName . -f $dockerfile

docker save -o $imageFilePath  $imageName # save 要搭配 load ; import 搭配 export

13.在專案根目錄,撰寫 powershell - Build Images( deploy.ps1 )

$containerName = "shopcart-1"
$containerUrl = "tcp://192.168.20.20:2376"
$imageName = "shopcart"
$outputPath = "./"
$imageFilePath = $outputPath + $imageName
$port="8888:80"

# 停用容器
docker --tls -H="$containerUrl" ps -a -f ancestor=$containerName --no-trunc -q | foreach-object { docker --tls -H="$containerUrl" stop $_ }
docker --tls -H="$containerUrl" ps -a -f name=$containerName --no-trunc -q | foreach-object { docker --tls -H="$containerUrl" stop $_ }

# 移除容器
docker --tls -H="$containerUrl" ps -a -f ancestor=$containerName* --no-trunc -q | foreach-object { docker --tls -H="$containerUrl" rm -f $_ }
docker --tls -H="$containerUrl" ps -a -f name=$containerName* --no-trunc -q | foreach-object { docker --tls -H="$containerUrl" rm -f $_ }

# 移除映像檔

$existingImages = docker --tls -H="$containerUrl" images $imageName
If ($existingImages.count -gt 1) {
write-host "[Removing image]Removing the existing image.."
docker --tls -H="$containerUrl" rmi -f $imageName
} else {
write-host "[Removing image]The image does not exist"
}

# 將本地的映像檔匯入 Docker 主機
docker --tls -H="$containerUrl" load --input  $imageFilePath
				
# 建立及啟動容器應用
docker --tls -H="$containerUrl" run -d --name $containerName --restart=always -p $port $imageName				

執行畫面

1. 當此專案有任何的 git commit 後,就會觸發 Gitlab 自動會建置

Gitlab Pipelines 列表顯示建置成功與失敗狀態
Gitlab Pipelines 列表顯示建置成功與失敗狀態

2. 建置完成後,當手動按下佈署時,會透過 Line 及 telegram 通知使用者部署狀態

App Monitor部署狀態通知聊天介面
App Monitor部署狀態通知聊天介面

最後

Gitlab Pipelines 真是個好東西,且完全免費,我一台伺服器都沒架,雲端Gitlab,搭配地端的 Runner ,就讓我輕易的做到 CICD ,並讓 Line Bot 通知相關人員,應用程式正在部署程式。

參考資料

參考資料
參考資料
參考資料
參考資料
參考資料

作者

Mark Ku

10 年以上的軟體工程師,做過北美電商與 AI SaaS 訂閱收費系統。現在經營貳陸資訊有限公司(www.226network.com),幫小公司做系統、網站、LINE BOT 與 AI 自動化,也在這裡分享開發筆記與開源工具。閱讀更多

覺得這篇有幫助?

作者做的免費工具、每日 Podcast 與電子報,都在這裡。

Mark Ku · 本文採用 CC BY 4.0 授權,轉載請註明作者並附上原文連結。

留言

訂閱電子報

訂閱後即時收到新文章通知,不錯過任何技術分享。

提交即表示同意接收電子報,隨時可

熱門文章

View all
Mark Ku
··655

Oracle Cloud 永久免費方案 Linux 主機及固定 IP :0 元打造雲端解決方案

Oracle Cloud 永久免費方案 Linux 主機及固定 IP :0 元打造雲端解決方案
Mark Ku
··574

告別 Postman 收費陷阱!開源 Git 原生 API 測試神器 Bruno 實戰指南

告別 Postman 收費陷阱!開源 Git 原生 API 測試神器 Bruno 實戰指南
Mark Ku
··318

一款免費開源類似於 Notion 類知識庫系統 — Outline Wiki 佈署與備份全攻略

一款免費開源類似於 Notion 類知識庫系統 — Outline Wiki 佈署與備份全攻略
Mark Ku
··234

訓練自己的 AI 語音:硬體門檻、開源模型比較與 LoRA 微調

訓練自己的 AI 語音:硬體門檻、開源模型比較與 LoRA 微調
Mark Ku
··231

在 Ubuntu 上設置 Samba 來共享資料夾,讓 Windows 11 用戶可以存取

在 Ubuntu 上設置 Samba 來共享資料夾,讓 Windows 11 用戶可以存取
Mark Ku
··225

打造高效 API 管理平台:從 0 開始部署 Kong Gateway - Part 1

打造高效 API 管理平台:從 0 開始部署 Kong Gateway - Part 1