---
title: "輕量化且免費，適用小團隊的 CICD - 使用 Gitlab Pipeline 及 地端 Gitlab Runner"
description: "說明如何使用免費的 GitLab Pipeline 搭配地端 Gitlab Runner，搭建適合小團隊的 CI/CD 環境，並整合 Telegram 與 Line Bot 推送部署通知。"
canonical_url: "https://blog.markkulab.net/post/gitlab-cicd-pipeline"
author: "Mark Ku"
author_url: "https://blog.markkulab.net/author/mark-ku"
site: "Mark Ku's Blog"
date_published: "2022-05-23 01:01:01 +0800"
category: "DevOps"
tags: ["cicd", "gitlab", "pipeline", "runner", "devops", "automation", "docker", "notification"]
language: "zh-TW"
license: "CC BY 4.0"
license_url: "https://creativecommons.org/licenses/by/4.0/"
attribution: "轉載或引用請註明作者並附上原文連結"
---

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

## 輕量化且免費，適用小團隊的 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手動佈版流程圖](https://blog.markkulab.net/content/markku/posts/gitlab-cicd-pipeline/images/yUafnv9.png)

### 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 ([可參考先前的文章](https://blog.markkulab.net/2021/12/30/qnap-nas-docker-powershell-deployed/))

### 2. 接著我們進入 Gitlab 後台 > Settings > CI/CD 
![GitLab專案頁面Settings選單中的CI/CD](https://blog.markkulab.net/content/markku/posts/gitlab-cicd-pipeline/images/Rxw8v9h.png)

### 3. 接著找到 Auto DevOps > Expand > 勾選 Continuous deployment to production > Save changes
![Gitlab CI/CD設定，Auto DevOps勾選持續部署到生產](https://blog.markkulab.net/content/markku/posts/gitlab-cicd-pipeline/images/KbYLZKR.png)

### 4. 在下面，我們可以 Runners > Expand > 關閉 Shared Runner，並複製 Gitlab CI url 及 token 起來，給地端的 Runner 註冊。
![GitLab Runner 設定介面顯示 CI URL 與](https://blog.markkulab.net/content/markku/posts/gitlab-cicd-pipeline/images/62IYFXm.png)

### 5. 安裝 gitlab-runner
```
choco install gitlab-runner
gitlab-runner --version  // 測試版本
```
[P.S. choco 使用教學](https://blog.markkulab.net/2021/06/03/powershell-install-docker/)
![GitLab CI/CD 設定頁面顯示 Runner 註冊令牌](https://blog.markkulab.net/content/markku/posts/gitlab-cicd-pipeline/images/QMFseXR.png)

### 6. 註冊 gitlab-runner 
```
gitlab-runner register
```
![PowerShell 終端機顯示 GitLab Runner 註冊成功](https://blog.markkulab.net/content/markku/posts/gitlab-cicd-pipeline/images/hb7Mwfc.png)

### 7. 啟動 runner 

gitlab-runner run

### 8. 當 Runner 起動後，此時 Gitlab 後台設定就會發現多了一個 Active 的 Runner，可以使用
![GitLab 後台 CI/CD Runner 列表顯示已啟動的](https://blog.markkulab.net/content/markku/posts/gitlab-cicd-pipeline/images/vqMxYIY.png)

### 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 列表顯示建置成功與失敗狀態](https://blog.markkulab.net/content/markku/posts/gitlab-cicd-pipeline/images/4gbRIqf.png)
### 2. 建置完成後，當手動按下佈署時，會透過 Line 及 telegram 通知使用者部署狀態
![App Monitor部署狀態通知聊天介面](https://blog.markkulab.net/content/markku/posts/gitlab-cicd-pipeline/images/7bZQ3UR.png)

## 最後
Gitlab Pipelines 真是個好東西，且完全免費，我一台伺服器都沒架，雲端Gitlab，搭配地端的 Runner ，就讓我輕易的做到 CICD ，並讓 Line Bot 通知相關人員，應用程式正在部署程式。

## 參考資料
[參考資料](https://blog.csdn.net/weixin_44723434/article/details/88425094)  
[參考資料](https://ithelp.ithome.com.tw/articles/1024238)  
[參考資料](https://dotblogs.com.tw/yc421206/2021/08/31/use_gitlab_runner_and_shell_exec_ci_cd_script_in_windows10#%E5%9C%A8%E6%9C%AC%E5%9C%B0%E7%AB%AF%E5%9F%B7%E8%A1%8C%20CI%20%E8%85%B3%E6%9C%AC)  
[參考資料](https://cache.one/read/16833817)  
[參考資料](https://www.cnblogs.com/tianyaguoke/p/11219648.html?fbclid=IwAR2SwAMnB-U44pT3HdThYsBfzzdC3rd35BSeWLI-mML8Fx6w3yILPDRoJFY)

---

## 關於本文與作者

本文出自 [Mark Ku's Blog](https://blog.markkulab.net/post/gitlab-cicd-pipeline)

授權條款： [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) — 轉載或引用請註明作者並附上原文連結

### 關於作者

**[Mark Ku](https://blog.markkulab.net/author/mark-ku)** — Software Solution Provider

- 10+ 年資深軟體工程師，現為 AI 應用 Builder
- 專注大型平台架構設計，從北美電商到AI SaaS訂閱收費系統
- 結合 AI Agent 與自動化，打造高效可演進的產品技術基礎

### 作者開發的免費工具

以下工具皆可免費使用：

- [免費 PDF 簽名工具](https://blog.markkulab.net/tools/pdf-sign): 線上 PDF 簽名工具，瀏覽器內完成手繪、打字、上傳簽名，可拖曳放置、縮放、下載。所有處理都在你的裝置完成，檔案不會上傳。
- [VS Code Refactory](https://blog.markkulab.net/tools/refactory): Refactory 是一款 VS Code 重構擴充套件：34 個重構動作、37 條 code smell 檢查、Code Health 儀表板、18 種語言、534 支測試。懂你的專案慣例：介面放哪、DI 註冊寫在哪、'use client' 該不該加；還會用 git 修改頻率 × 複雜度排出「該先修哪個檔案」，並一鍵把壞味道交給你自己電腦上的 Claude Code 修。免費使用，原始碼不離開你的機器。
- [DB-Kit 資料庫管理工具](https://blog.markkulab.net/tools/db-kit): DB-Kit 是一個用 Tauri + Rust + React 打造的輕量跨平台資料庫管理工具，用單一一致的介面同時管理 MySQL、MariaDB、PostgreSQL、SQL Server、Oracle、SQLite、MongoDB、Redis、Kafka、Elasticsearch 與 RabbitMQ 十一種資料來源：連線密碼以 OS keychain 加密、SSH Tunnel、完整 CRUD、視覺化查詢建構器、多結果集同時顯示、跨連線資料傳輸與比對同步、Excel / CSV 匯入匯出、執行計畫視覺化、ER 圖、排程備份、SQL 壓力測試（p50～p99 延遲百分位）、15 條規則的 SQL 審查、Kafka 訊息瀏覽與監控告警；繁中 / 英文雙語介面，內建 AI 助手（自然語言生成 SQL、AI 審查與調校建議）與命令列工具 dbk。免費開源（MIT），提供 Windows / macOS / Linux 安裝檔。
- [VS Code Super Mermaid](https://blog.markkulab.net/tools/super-mermaid): Super Mermaid 是一款 VS Code 擴充套件：開箱即用的漂亮 Mermaid 圖表，自動上色、即時預覽、滑鼠平移縮放、PNG / SVG 高解析匯出，內建 21 種範本與多種主題。免費開源（MIT）。
- [React Super Mermaid](https://blog.markkulab.net/tools/react-super-mermaid): react-super-mermaid 是一個開源 React 元件庫：一行 <MermaidViewer> 即可渲染漂亮的 Mermaid 圖表，內建 colorful / sketch 主題、平移縮放、圖內搜尋、SVG / PNG 高解析匯出。輕量、SSR 安全、完整 TypeScript 型別。免費開源（MIT）。
- [Jira / Confluence Super Mermaid](https://blog.markkulab.net/tools/jira-super-mermaid): Atlassian Forge app：在 Jira issue 與 Confluence 內文直接寫 Mermaid 語法，畫流程圖、時序圖、狀態機與甘特圖。11 種圖表、SVG / PNG 匯出、明暗主題、完整中日韓文字支援。取得 Runs on Atlassian 資格：圖表存在你自己的站台，app 不呼叫任何第三方服務。免費，即將上架 Atlassian Marketplace。
- [Mermaid 線上預覽](https://blog.markkulab.net/tools/mermaid-preview): 在瀏覽器裡寫 Mermaid、即時看圖，整張圖表壓進網址就能分享。免註冊、不上傳伺服器，相容 mermaid.live 的分享連結。
- [React Intl Phone Number](https://blog.markkulab.net/tools/react-intl-phone-number): react-intl-phone-number 是一個開源 React 元件：framework-agnostic、不依賴 antd，提供 E.164 進出、可搜尋國旗 / 國碼下拉、可配置驗證等級（strict / mobile-strict / loose）、可主題化 CSS 與 i18n，電話邏輯由 google-libphonenumber 驅動。輕量、完整 TypeScript 型別。免費開源（MIT）。
- [Uptime Kuma Cluster](https://blog.markkulab.net/tools/uptime-kuma-cluster): 把單機版 Uptime Kuma 改造成高可用叢集：OpenResty + Lua 智慧負載平衡、MariaDB 共享狀態、健康檢查與自動 Failover，附叢集管理 REST API，一行 Docker Compose 啟動。免費開源（MIT）。
- [特教專案](https://blog.markkulab.net/education): 為特殊教育學生製作的學習教材

### 每日 Podcast

- [科技新鮮事](https://blog.markkulab.net/category/tech-news): 每日精選 AI 與科技趨勢，透過語音摘要快速掌握最新技術動態，涵蓋 AI 應用、軟體架構、DevOps 與工程實戰。 — RSS: https://blog.markkulab.net/feed.xml
- [AI股市蝦聊](https://blog.markkulab.net/category/ai-stock-chat): 每個交易日用 AI 分析台股盤勢，以雙人對話聊當天的盤中觀察與隔日預測。 — RSS: https://blog.markkulab.net/ai-stock-chat/feed.xml

### 電子報

[訂閱電子報](https://blog.markkulab.net/subscribe) — 第一時間收到新文章通知，無垃圾信、隨時可取消訂閱。
