[生活筆記] 2023 半年工作回顧

前情提要

這份是 2023 年, 3 至 6 月間,我在工作上獲得的成果,
以理性務實的態度推動各項工作,以下是在這段時間內所取得的重要成果:

敏捷觀念的引進與實踐

我引進了迭代開發要事優先的敏捷觀念,
同時建立了 PBI(產品待辦項目)與工作看板,以確保團隊的工作透明度
我們每日召開立會,及時更新資訊,並建立了文件系統,以便於知識的分享與傳承。

前後端分離的優化

我推動了前後端分離的工作方式,使專業得以適當分工,減少了彼此等待的時間。
這樣的優化使得服務可以被重複使用,避免了重複開發,節省了寶貴的時間與資源。

自動化的部署機制引入(CI/CD)

我們成功建立了自動化的部署機制,每次部署都節省了至少 10~30 分鐘的時間,
同時大幅減少了人工操作可能帶來的錯誤風險
這項優化為團隊帶來了高效率與更穩定的工作環境。
這是持續性的正面效益,假設每周部署 10 人次以上,以換算時薪為 600 計算,
每年每位 RD 約可以省下等值於 8 萬的工作時間。並大幅下降風險。

準時交付 N 系統,完成參展目標

我們順利地在新加坡、法國、台北和高雄四地參展,並提供了展場現場的支援,
這已超出我們本職專業的範疇。
但我們成功地達成目標,贏得了更多的曝光與商機。

帶回自主開發的 I 上鏈系統,省下外包費用

為了節省成本,我們將原本要外包的 I 上鏈系統帶回自主開發,從而節省了公司大筆的費用與時間。
這項舉措不僅讓我們獲得了更多的控制權,還提升了整體效率。
此項目,粗估至少擁有 300 萬以上的產值。

其他突破與調整

除了以上成果,我還做了以下貢獻:

  • 解決了公司 domain 數量達到上限的問題,通過與系統商的溝通,成功解除了限制。
  • 幫助查找了未關閉的 AWS 資源,避免了資源的浪費。
  • 調整了資安需求,提高了系統的安全性。
  • 協助調解了系統與需求之間的衝突,確保了順利推進工作。
  • 未來的發展計劃
  • 為了持續推動工作的進步,我擬定了以下計劃:

下一步

  • 將預計外包的 P 系統帶回自主開發,進一步節省公司費用。粗估其價值為 110~800 萬之間。
  • 積極招募人才,引進新血,提升團隊實力。
  • 推進單雲轉多雲的轉型,增加靈活性與彈性。
  • 針對資安問題進行調整,包括關閉公開 IP 和加密資料等措施。
  • 處理舊系統 L 的大泥球,逐步優化系統結構,提高整體效率。

結論

整體而言,在短短三個月內,接手的專案已為公司撙節了 150 萬 左右的支出,
而在自動化工具,用一個粗略評估的方式,假設每周每個 RD 會部署 5 次,
一年 52 周,一次部署可以省下 10 分鐘的情況下,目前公司 5 位 RD:
5*5*52*10= 13000 分鐘,大約可以省下 1.25 個人月,用來作更有意義的事。
而其它工作在長久看來也會持續帶來收益,整體而言,這三個月的產值已超過 500 萬
希望在未來的日子裡,能夠持續取得進步,為公司的發展做出更大的貢獻。

(fin)

[實作筆記] GitHub Actions:停用 save-state 和 set-output 命令的措施

前情提要

GitHub Actions 是一個強大的自動化工作流程工具,可讓您在 GitHub 存儲庫中執行各種自動化任務。
它允許您根據事件觸發工作流程,例如提交代碼或創建拉取請求。
您可以使用預設的操作或自定義操作來建立工作流程,並將其用於自動化測試、部署、持續集成等開發流程。
GitHub Actions 提供了一個靈活、可擴展和可自訂的方式來增強您的開發工作流程。

而我實務上的情境是用來寫 Blog,並進行自動部署,而我注意到了一個警告訊息。

1
Warning: The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/

問題

在 Github 的官方 Blog 指出,自 CI Runner 版本 2.298.2 起,
如果用戶在使用 save-state 或 set-output 將開始發出警告。
並計劃在 2023 年 5 月 31 日完全禁用它們。
從 2023 年 6 月 1 日開始,使用 save-stateset-output 命令的工作流程將因錯誤而失敗。

補充

實際上根據 Github 觀測數據顯示,這些命令的使用率相當高。
考慮到受影響的客戶數量,而推遲了移除的時間。

我的情況

為什麼我會用到這值呢?看看我的 CD 部署檔

1
2
3
4
5
6
7
8
9
10
11
12
13
## Skip ...
step:
# Deploy hexo blog website.
- name: Deploy
id: deploy
uses: marsen/[email protected]
with:
deploy_key: ${{ secrets.DEPLOY_KEY }}
- name: Get the output
run: |
echo "${{ steps.deploy.outputs.notify }}"

## Skip ...

在我這裡有兩步驟,Deploy  與 Get the output
Deploy 直接用了我的另一專案進行部署,內部的工作簡單的說明如下:

  1. 用 Dockerfile 建立執行環境
  2. 拉取 Hexo Blog
  3. 執行相關指令 ex: hexo g
  4. 部署完成印出成功訊息

問題就出在這個第四步,在 Github Runner 啟動的 image 執行過程的輸出,
並不會顯示在 Action Steps 的 Output 資料之中。
所以在這個專案多作一步 Get the output 來印出這個訊息。

1
2
3
- name: Get the output
run: |
echo "${{ steps.deploy.outputs.notify }}"

可以知道我們的訊息是放在 steps.deploy.outputs.notify 之中,
而原始接出資料的方式如下,這個作法即將被逃汰了(為了避免無意間的資訊外洩)

1
echo ::set-output name=notify::"Deploy complate."

解決方式

如果官方 Blog 所說,你只要將 key-value 用以下的形式設定到環境變數 $GITHUB_OUTPUT 即可,

1
echo "{key}={value}" >> $GITHUB_OUTPUT

舉例來說:

1
2
result="Deploy complate."
echo "notify=$result" >> $GITHUB_OUTPUT

參考

(fin)

[踩雷筆記] 移除 VM 外部 IP 後 GCS 檢查異常的問題

前情提要

我們使用 GCP Compute Engine 建立 VM,並且配置了一個對外的 IP(External IP),
同時設定了一個排程,定期將 VM 上產生的資料轉存到 GCS(Google Cloud Storage),
我們主要使用的工具是 gcloud 並且在 VM 上設定了某個 Service Account,
並且一切運作順利。

某日因為資安考量我們移除了 VM 的 External IP,而搬檔到 GSC 的排程就異常了。
我們簡單使用以下指令作檢查

1
gcloud storage ls

這個指令會列出我們 GCS 上的資源,
當 VM 有 External IP 時一切運作正常,而移除時會無回應。

解決方法

這裡只需要修改 GCP 的 VPC 設定,
選擇 subnet (ex:asia-east1,看你的 VM 在哪個 Zone)
啟用 Private Google access 為 On 然後存檔

參考

(fin)

[實作筆記] GCP 使用 IAP 連線 VM

簡介 IAP(Identity-Aware Proxy

GCP 的 IAP(Identity-Aware Proxy)是一個身份驗證和授權服務,
用於保護和管理對 Google Cloud 資源的訪問。
它提供了對虛擬機器(VM)實例的安全連接和控制,並可用於 SSH、RDP 等流量的安全轉發(Forwarding)。

通過 IAP,我們可以實現零信任訪問模型,僅允許經過身份驗證和授權的用戶訪問資源,
並且可以根據用戶的身份和上下文進行細粒度的訪問控制。
這提高了資源的安全性並減少了潛在的安全風險。

零信任訪問模型

零信任訪問模型(Zero Trust Access Model)是一種安全設計方法,該方法不假設內部網絡是可信的,
並對每個訪問請求進行驗證和授權,無論該請求來自內部還是外部網絡。
在零信任模型中,所有訪問都需要通過驗證和授權,並且需要進一步的身份驗證和授權步驟,
以確定用戶是否具有訪問資源的權限,更多可以查看參考資料。

比較 VPN 與 RDP

其他常見的連線方式包括傳統的虛擬專用網絡(VPN)和遠程桌面協議(RDP),
它們通常用於在企業內部建立安全連接,但對於雲環境和遠程用戶來說,這些方法可能不夠靈活和安全。

IAP 提供了一個更強大和安全的連接方式。
它在零信任訪問模型下工作,通過驗證和授權機制確保只有經過驗證的用戶可以訪問資源。
以下是 IAP 的優勢:

  • 精確的身份驗證和授權:IAP 可以根據用戶的身份和上下文進行細粒度的訪問控制,僅允許授權的用戶訪問資源。
  • 無需公開 IP 地址:IAP 通過提供 IAP 隧道和代理服務,不需要公開資源的實際 IP 地址,增強了安全性。
  • 雲原生和易於使用:IAP 是 GCP 的原生服務,與其他 GCP 服務整合,易於設置和管理。

前情提要

客戶在 GCP 上部署了多台 VM,每個 VM 都有公開的外部 IP 地址,並允許開發者使用 SSH 進行連線。
這樣的設置存在著安全風險,也需要為這些公開的 IP 付出額外的成本。

為了提高安全性並解決這個問題,我們使用 GCP 的 IAP(Identity-Aware Proxy)。
透過 IAP,我可以實現更安全的連線方式,不需要使用 Public IP 。
IAP 提供了精確的身份驗證和授權,只有經過驗證的使用者才能訪問 VM。
這種設置符合零信任訪問模型,提高了資源的安全性,同時減少了潛在的安全風險。

實務操作

我有一台測試用的 VM beta 已經拔除了 public IP,

  1. 首先啟用(enable) Cloud Identity-Aware Proxy API,「Security」->「Identity-Aware Proxy」

  2. 在 IAM > Permissions 找到需要登入 VM 主機的帳戶加上「IAP-secured Tunnel User」這個角色

  3. 防火牆規則,IP Range: 35.235.240.0/20, 開通指定的 Protocols and ports,比如我們要 SSH 連線,就開通 tcp:22,Targets 設為 Specified targets tags Target tags 為 ingress-from-iap,

  4. 需要登入 VM 加上 tag ingress-from-iap

  5. 可以用以下語法測試連線

    1
    gcloud compute ssh beta --project=my-project --zone=asia-east1-c --troubleshoot --tunnel-through-iap
  6. 排除所有問題後嚐試連線

    1
    gcloud compute ssh beta --project=my-project --zone=asia-east1-c --tunnel-through-iap

補充說明

  • 開發環境在連線時已經透過 gcloud auth login 取得權限了。
  • 連線的目標主機仍然需要設定 SSH 金鑰
  • 35.235.240.0/20 是 GCP 中 IAP 使用的特定 IP 範圍,不可修改

20230711 補充

透過 IAP 連線會出現 “Increasing the IAP TCP upload bandwidth” 的警告
可以參考官方文件

下載 Numpy

1
$(gcloud info --format="value(basic.python_location)") -m pip install numpy

設定環境變數

1
export CLOUDSDK_PYTHON_SITEPACKAGES=1

參考

(fin)

[生活筆記] 歌的故事-我也很想他

寫在前面

有時候聽到一些歌,會覺得很有畫面感,甚至有一個故事。
會想要了解,但是隨著時間流逝,這些資訊會越來越難取得。
如果有找到的話,就放在這裡備份吧。

我也很想他 – 孫燕姿

資料來源

e娛樂 updated: November 26, 2004 17:54

e歌樂全盒
彭學斌我也很想他

報導:王慧霞

故事

彭學斌因為陳穎見
寫下我也很想他

“一波三折”,可說是《我也很想他》的最佳寫照。

這首由大馬知名音樂人彭學斌填詞譜曲的《我也很想他》,在歷經兩度被退歌的命運后,
在轉轉折折之間,竟然落在亞洲小天后孫燕姿的手中,並且收錄在“東山復出”的專輯《
Stefanie》之中。

與此同時,《我》亦成了目前最受矚注的日本電影《在世界的中心呼喊愛情》台灣中文主
題曲,無疑為這首訴說一段淡淡情愁的情歌中,倍添了幾分秋天的落寞。

“歌曲背后的故事,我想是因為思念而開始了這首歌的創作。記得有一天,陳穎見的妹妹
專程來找我喝茶聊天,聊著聊著就聊起了遠在國外唸書的穎見。回到家之后,她突然傳了
個簡訊給我,告訴我說:我真的很想他(穎見);于是,我回簡訊給她,告訴她,我也很
想他。突然間,我泛起了一絲絲的靈感,就把當下的心情寫成歌詞,于是就有了這首歌的
誕生。”學斌如是說。

接著,經由版權公司的大力推薦,學斌便把這首歌交給當時一位正在收歌的台灣女新人演
唱,結果因曲風不適合而被彈回票,之后交由另一位偶像男歌手聽時,結果還是不獲青睞
。不過,有麝自然香,在幾經波折之下,這首歌卻落在了燕姿手中,叫他既意外又欣喜。

學斌透露,這首歌原本是決定收錄在燕姿“暫休”前的上一張的新歌加精選專輯當中,但
她和制作人的要求都頗高,一直覺得還唱不出這首歌所要的感覺,所以歌詞一修再修,挪
至1年后才見天日。

學斌欣慰地表示:“我不怕等待,只要對的人出現,那就是對的時機。”

對于修詞一事,學斌表示若符合歌手本身的特質,他倒是不介意。他表示,這首歌雖然被
修改了逾40%,由他對友人的思念意境,改為現在大家所看到的版本,但慶幸沒有乖离他
的本意,而燕姿深情的演繹,亦讓他倍覺感動。

學斌續指出,經過April的修改之后,把歌曲意境轉為是在訴說著兩女一男的感情故事。
透過燕姿的眼光,看著一對好友的經過相愛、傷害的情景,畫面楚楚動人,再加上悠悠的
旋律,輕易就勾起人們對于思念的因子。

(fin)

[實作筆記] MongoDB 解決方案評估-- Mongo Atlas

前情提要

最近在 VM 部署了 MongoDB, 不知道為什麼同事在 QA 與正式環境採取了兩個不同的作法,
因此產生了一些版本不一致的問題。
為此需要更換 MongoDB 版本,進而有一些討論,  
決策的考量主要有兩個面向,一、維運的成本。二、實際應付的帳務成本。
可行的方案比較如下,

  • VM 部署 MongoDB
    • GCP
    • Azure
    • Other Cloud …
  • Mongo Atlas(Start from GCP Marketing)
    • GCP VM with MongoDB(Pay as You Go)
    • Azure VM with MongoDB
  • Azure CosmosDB

實作隨筆:Mongo Atlas(Start from GCP Marketing)

測試規劃

mongo atlas 連線的測試架構

如圖,為了不影響原有的環境,我打算建一組新的 VPC Network 進行實驗,
並在這個網路中建立一台實體的 VM 機器,待 Mongo Atlas 設定完成後,
進行連線的測試。

測試的方法,由於 MongoDB Atlas 採用一種安全性較高的連線政策,
必需使用以下連線集群的三種方式才可以連到資料庫:
第一種,IP Access List,使用 GUI 建立 Cluster 的當下會自動加入一組你所在網路對外的 IP,
如果不是固定 IP 可能會有問題
第二種,Peering ,要付錢的版本 M10 以上才可用,也是我們這次實作的重點目標
最後一種,Create a Private Endpoint,也是
M10 以上才可用,但是不是我們這次的主要實作項目,所以不過多的展開。

從 GCP Marketing 建立 Mongo Atlas

在 GCP 的 Marketing 搜尋並訂閱 Mongo Atlas 後點擊 MANAGE ON PROVIDER
在 Mongo Atlas 建立 Cluster,也可以建立 Project 與 User 作更細緻的管控。
這時候可以到 Network Access 查看 IP Access List 的清單,應該會有你網路上設定的對外 IP,
這個流程是自動化的,但是我個人認為不是固定 IP 的話可能會有問題,如果有人可以給我一些提點會十分感激。

IP Access List

建立 VM

GCP 建立 VM 是十分簡單的,就不多作說明。
同時記得安裝我們的測試工具 - mongosh

Mongo DB 相關

切換 db

1
use mydb

查詢目前 DB 狀態

1
db.status()

Create User

1
db.createUser({ user: "username", pwd: "password", roles: [{ role: "roleName", db: "databaseName" }] });

Drop User

1
db.dropUser("username");

查詢 User

1
db.getUsers()

User 加入角色

1
db.grantRolesToUser("username", [{ role: "readWriteAnyDatabase", db: "mydb" }])

User 移除角色

1
db.revokeRolesFromUser("usernmae", [{ role: "readWrite", db: "admin" }])

前置作業: GCP VPC 與 Firewall Rules 設定

為了避免影響原有的系統,
建立 GCP 一組新的 VPC Network : vpc-lab,一般來說 GCP 的專案會有自動建立一組 default VPC Network,
default VPC Network 會預設建立以下的防火牆規則

  • default-allow-icmp – 允許來自任何來源對所有網路 IP 進行存取。ICMP 協議主要用於對目標進行 ping 測試。
  • default-allow-internal – 允許在任何埠口上的實例之間建立連接。
  • default-allow-rdp – 允許從任何來源連接到 Windows 伺服器的 RDP 會話。
  • default-allow-ssh – 允許從任何來源連接到 UNIX 伺服器的 SSH 會話。

與此對應,我也建立相同的規則給vpc-lab,如下:

  • vpc-lab-allow-icmp
  • vpc-lab-allow-internal
  • vpc-lab-allow-rdp
  • vpc-lab-allow-ssh

可以用以下的語法測試一下網路是否能連,如果可以連線再進行 mongodb connection 的測試

1
ping {ip address}
1
telnet {ip address} {port}
1
nc -zv {ip address}

測試連線用的語法

如果網路測試沒有問題,再進行 mongodb 的連線,由於目前沒有設定 Peering 連線,
所以在開發機上可以(網路環境需要在 IP Access List 內),而使用 GCP VM 會無法連線,
開發機連線 GCP MongoDB 語法

1
mongosh mongodb://{user:pwd}@{mongodb_ip}:27017/my_db

開發機連線 MongoDB Atlas 語法

1
mongosh mongodb+srv://{user:pwd}@{atlas_cluster_name}.mongodb.net/my_db

Peering 實作

首先需要在 Mongo Atlas 進行設定,
Network Access > Peering > Add Peering Connection
在 Cloud Provider 中選擇 GCP,

Mongo Atlas Setting

設定 Project ID、VPC Name 與 Atlas CIDR,
比較特殊的是 Atlas CIDR 在 GUI 的說明是

An Atlas GCP CIDR block must be a /18 or larger.
You cannot modify the CIDR block if you have an existing cluster.

但我遇到的狀況是,無法修改預設值為 192.168.0.0/16
建立後會產生一組 Peering 的資料,請記住 Atlas GCP Project ID 與 Atlas VPC Name

Mongo Atlas Peering

接下來到 GCP > VPC Network > GCP Network Peering 選擇 Create peering connection
在 Peered VPC network 中選擇 Other Project,並填入上面的 Atlas GCP Project ID 與 Atlas VPC Name

大概等待一下子就會生效了(網路上寫 10 分鐘,實測不到 3 分鐘)

參考

(fin)

[實作筆記] RWD 設計與 100vh 在行動裝置瀏覽器上的誤區

前情提要

參考圖片

RWD 設計與 100vh 在行動裝置瀏覽器上的誤區

我的網頁有作 RWD 的設計,需求大概是這樣,
綠色是在網頁底部懸浮的選單功能,
紅色區塊是一個控制面版,許多的功能、按鈕、連結都設定在上面。

我最一開始的設定方法如下,

1
height: 100vh;

在瀏覽器上使用模擬器顯示正常,但是在手機上就會出現異常
主要是手機上的 Chrome 和 Firefox 瀏覽器通常在頂部有一個 UI(例如導覽列及網址列等)  
而 Safari 更不同網址列在底部,這使得情況變得更加棘手。
不同的瀏覽器擁有不同大小的視窗,手機會計算瀏覽器視窗為(頂部工具列 + 文件 + 底部工具列)= 100vh。
使用 100vh 將整個文件填充到頁面上時可能導致顯示問題,因為內容可能超出視窗範圍或被遮擋。
因此,在移動設備上進行響應式設計時,應該避免使用 100vh 單位。

解決方法

解決的方法有好幾種,

JS 計算

使用 JavaScript 監聽事件,動態計算高度,缺點是效能較差,在主流的框架(EX:React)要小心觸發重新渲染的行為

1
2
3
4
5
6
const documentHeight = () => {
const doc = document.documentElement
doc.style.setProperty('--doc-height', `${window.innerHeight}px`)
}
window.addEventListener(‘resize’, documentHeight)
documentHeight()

CSS 變數

使用 CSS 變數

1
2
3
4
5
6
7
8
9
10
11
:root {
--doc-height: 100%;
}

html,
body {
padding: 0;
margin: 0;
height: 100vh; /* fallback for Js load */
height: var(--doc-height);
}

min-height 與 overflow-y

留言有人提到使用min-heightoverflow-y
但我的情境不適合,而且這個作法會產生捲軸

1
min-height: 100vh;
1
2
height: 100vh;
overflow-y: scroll;

進一步依照不同的使用情境也許我們需要 @supports

1
2
3
4
@supports (-moz-appearance: meterbar) {
/* We're on Mozilla! */
min-height: calc(100vh - 20px);
}

或是 Browser Hacks 的手法

1
2
3
4
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
/* We are on Internet Explorer! */
min-height: calc(100vh - 10px);
}

position:fixed 的作法

下面的方法可以將元素固定在畫面底部

1
2
3
4
position: fixed;
left: 0;
right: 0;
bottom: 0;

這是我最後選擇的方法,原文的討論相當精彩有趣,
但是我需要的其實是置底,而不是捲軸。
順帶一提我的專是基於 vue 與 tailwindcss,所以下面是 vue 與 tailwindcss 的寫法

1
2
3
<div class="fixed bottom-0 top-0">
<!--HERE THE FEATURES-->
</div>

參考

(fin)

[實作筆記] 管理 Linux 主機與 GCP VM 的磁碟

前情提要

在 GCP VM 上建立的 GitLab Runner 空間不足,導致執行失敗。
我們需要確保 GitLab Runner 有足夠的存儲空間來運行 CI 的 Jobs 。
有兩個解決方案可供選擇:
一、是清理磁碟空間
透過清理磁碟空間,可以移除不需要的文件和暫存資料,釋放寶貴的儲存空間。
二、是擴展磁碟空間
而擴展磁碟空間則是增加磁碟的容量,讓 GitLab Runner 可以持續運行而不受空間限制。
根據具體情況,可以選擇其中一種或兩種方案來解決空間不足的問題

第一部分:查詢與清理磁碟空間

要查詢 Linux 主機的磁碟空間,可以使用 df 命令。下面是使用 df 命令查詢磁碟空間的語法:

1
df -h

這將顯示磁碟空間的使用情況,包括每個檔案系統的大小、已使用的空間、可用的空間以及使用百分比。
要查詢特定目錄或資料夾的磁碟使用情況,可以使用 du 命令。以下是使用 du 命令查詢磁碟使用情況的語法:

1
du -h --max-depth=1 /path/to/directory

這將顯示指定目錄或資料夾的磁碟使用情況,並以人類可讀的格式顯示結果。
可以查詢到一些 cache 或是 log 如果沒有必要的話,可以將之刪除。

要清除 Docker 的磁碟空間,可以使用以下語法:

1
docker system prune -f

第二部分:擴展 GCP VM 的磁碟空間

要在 GCP VM 上垂直擴展 boot 磁碟空間,可以按照以下步驟進行操作:

在 GCP 控制台上,找到並選擇要擴展的 VM 實例。

  • 停止 VM:前往 VM instances 找到要停止的 VM,勾選後 STOP
  • 調整:前往 Disks,找到要 VM instances 所用的 Disk,點擊 Edit 後增加磁碟的大小。
  • 啟動 VM 實例。

小結

無論是清理磁碟空間還是擴展磁碟空間,都是為了讓我能確保足夠的空間供 GitLab Runner 使用,
確保順利運行 CI Jobs!

(fin)

[踩雷筆記] Hexo 網站跑版

前情提要

我的部落格是基於 Hexo 建立的靜態網站,
前幾天,我發佈了一篇新文章,但樣式出現了錯亂。
為了了解發生的問題與解決方案,必須先知道我們的架構,
相關的有三個儲存庫:

Gitlab Group

Github Page

這是部落格的主要內容,使用 Github Page 部署。
通常情況下,我們不會直接對它進行修改,因為大部分的更動都是透過串接的 Github Action 自動完成的。
這個儲存庫代表了整個流程的最終成果。

hexo action

這是我們的自動化工具,結合 Github Action 可以實現持續集成與部署(CI/CD)。
雖然平時不太需要特別注意,但它是相當重要的一環。

Source

這是我們撰寫文章的主要地方,也是整個部落格的功能和版面設計的編排處。

問題追蹤記錄

首先檢查了網頁載入的樣式,發現找不到 style.css 檔案,但有 style.styl
為了緊急處理,我先提供一個正確的 style.css

幸好我在本地端能夠生成正確的 style.css 檔案,所以我先緊急上傳了一個版本到 Github Page
重新執行本地端的測試,一切正常。再次進行部署,結果樣式又跑掉了。
於是我再次手動修正了 Github Page 的問題。

追查了一下 Github Action,發現在這個 commit 之後,異常情況開始發生:

1
2
-"hexo-renderer-stylus": "^2.1.0",
+"hexo-renderer-stylus": "^3.0.0",

從這個記錄中可以得知,問題出在 hexo-renderer-stylus 的更新,而且是一個較大的版本變動。
接下來我嘗試在本地端測試,但卻沒有發現問題。
我開始思考是不是我的部署環境(CI/CD)與本機環境的差異,
第一個是 Node 版本太舊了(12.x.x),所以我先更新了本機的 Node 版本到 20.x.x。
所以我修改了 hexo action,使用最新的 Node 20.x 版本的映像檔。
然而,重新執行部落格的持續部署作業仍然失敗,無法產生 style.css

盲點與解決方式

在這裡我卡住了很久,始終找不到原因。
再次梳理持續部署的流程,結果發現我使用的 hexo-action 版本為 v1.0.5。
原來我忽略了一個步驟,需要為 hexo action 添加新的標籤。
此外,在我們的 Source 的流程中(.github/workflows),
也需要修改為新的 action 標籤 uses: marsen/[email protected]

1
2
3
4
5
    # Deploy hexo blog website.
- name: Deploy
id: deploy
- uses: marsen/[email protected]
+ uses: marsen/[email protected]

(fin)

[實作筆記] 基於 Docker 的 CI Docker 映像檔加速構建流程

前情提要

在現代軟體開發的流程中,持續整合(Continuous Integration,簡稱 CI)是一個重要的概念,
它可以幫助開發團隊在頻繁的程式碼變更中保持項目的穩定性和品質。
而 Docker 作為一個輕量級的容器技術,在 CI 中也扮演著重要的角色。
本篇文章將介紹一個基於 Docker 的 CI Docker 映像檔(Dockerfile_project)的實作記錄(手動,未來將調整為自動化)。

實作

首先,這個 CI Docker 映像檔是基於 php:8.x 映像檔建立的,並且預先安裝了 composer 和 ext-mongodb 擴展。
這樣開發團隊在進行 PHP 項目的 CI 時,就可以直接使用這個映像檔,而不需要額外安裝這些依賴。

在開始使用之前,我們需要訪問 GitLab 的 Docker Registry,所以我們首先需要創建一個 Token。
在 GitLab 的項目設置中,可以找到「Settings > Repository > Deploy tokens」,
在這裡我們需要勾選「read_registry」和「write_registry」權限,以便於讀取和寫入映像檔。

接下來,我們需要使用以下指令來登錄到 GitLab 的 Docker Registry:

1
docker login $GITLAB_REGISTRY_URL -u $GITLAB_REGISTRY_USERNAME -p $GITLAB_REGISTRY_TOKEN

登錄成功後,我們就可以開始建立映像檔了。使用以下指令可以建立映像檔:

1
docker build -t registry.gitlab.com/my_group/subgroup/project .

如果你的電腦跟我一樣是 Mac M2 晶片,可以使用以下指令進行建立:

1
docker buildx build --platform linux/amd64 -t registry.gitlab.com/my_group/subgroup/project --load .

最後,我們需要將建立的映像檔推送到 GitLab 的 Docker Registry 中:

1
docker push registry.gitlab.com/my_group/subgroup/project

至此,我們已經完成了 CI Docker 映像檔的建立和推送的過程。
現在開發團隊可以在持續整合的過程中使用這個映像檔,從而確保項目的穩定性和品質。

小結

在本文中,我們介紹了一個基於 Docker 的 CI Docker 映像檔(Dockerfile_project)的實作步驟。
透過這個映像檔的建立和使用,開發團隊在持續整合(CI)過程中取得了顯著的效率提升。

使用這個新的 Docker 映像檔後,我們見證了從原本的 4 分鐘大幅改進至僅需 30 秒的驚人效果。
這意味著開發團隊現在能夠更快速地完成整個 CI 流程,並且在更短的時間內獲得即時的反饋。

這種效率的提升主要歸功於 Docker 的輕量級容器技術,以及映像檔中預先安裝的依賴(如 composer 和 ext-mongodb)。
透過這些優勢,開發團隊可以在相同的硬體資源下更有效地執行構建和測試操作,從而節省了寶貴的時間。

因此,使用這個新的 Docker 映像檔對於任何需要進行持續整合的專案來說都是一個明智的選擇。
它不僅能提升開發團隊的效率,同時也能確保項目的穩定性和品質。

(fin)