Docker BuildKit Cache Mount 的隱形陷阱

症狀:部署成功,程式碼卻是舊的 一個新功能已經 commit 並推上 Git,Jenkins pipeline 顯示建置成功、部署完成,Kubernetes Pod 也順利啟動。進入 Pod 檢查——程式碼還是舊的。 這不是網路延遲、不是 image pull policy、不是 tag 衝突。問題藏在 Dockerfile 裡一行看起來「很聰明」的快取優化。 背景知識:Docker 建置的關鍵概念 在進入除錯過程之前,先釐清幾個 Docker 建置中的核心概念: Docker Image 與 Layer(映像檔與分層) Docker 映像檔由多個唯讀的「層」(layer)堆疊而成。Dockerfile 裡的每一條指令(如 COPY、RUN)都會產生一層。Docker 會對每一層計算 hash,下次建置時如果指令和輸入都沒變,就直接重用該層——這就是 layer cache。 BuildKit BuildKit 是 Docker 18.09 之後引入的新一代建置引擎(透過 DOCKER_BUILDKIT=1 啟用)。相比傳統引擎,BuildKit 支援平行建置、更聰明的快取策略,以及本文主角——--mount=type=cache(cache mount)語法。 Cache Mount(--mount=type=cache) BuildKit 專有的功能。它在 RUN 指令執行期間,將一個持久化的目錄掛載到容器內的指定路徑。這個目錄由 BuildKit 管理,不會被寫入最終的 image layer,但內容會跨越不同次的 docker build 保留下來。常見用途是快取套件管理器的下載目錄(如 yarn cache),避免每次建置都重新下載。 Inline Cache 與 --cache-from 另一種 BuildKit 快取策略。透過 --build-arg BUILDKIT_INLINE_CACHE=1 把快取 metadata 嵌入產出的 image,再用 --cache-from 從遠端 registry 拉取。這讓不同機器(例如 CI runner)也能共享建置快取。 ...

February 18, 2026 · 2 分鐘 · Peter

功能部署後憑空消失?一場 Jenkins Workspace 的除錯之旅

問題:功能「先在後不在」 我們替 Strapi 後台新增了 MFA(Multi-Factor Authentication)雙因素認證功能。第一次部署到 STG 時一切正常——登入攔截、TOTP 驗證、QR Code 設定流程都運作良好。 但幾天後,因為其他功能的修改推了新的 git tag stg-1.24,部署流程順利完成,Jenkins 顯示綠燈——打開 STG 後台,MFA 的登入流程卻完全不見了。 沒有錯誤訊息、沒有 crash log,功能就這樣無聲無息地消失。 這比「功能從未出現」更令人困惑:明明之前部署是好的,程式碼也沒有人動過 MFA 相關的部分,為什麼會突然不見? 調查過程:逐層排除 確認 Git Tag 內容 第一個直覺是——程式碼真的有被包進 tag 嗎? # 確認 tag 指向的 commit 包含 MFA 程式碼 git show stg-1.24:src/index.ts | grep -i mfa 結果確認 src/index.ts 中有 import { registerMfaRoutes } from './mfa/controller',src/mfa/ 目錄也完整存在。Git tag 本身沒問題。 檢查 Pod 內的實際檔案 既然 tag 正確,問題可能出在建置或部署階段。直接進到 Kubernetes Pod 裡看: # 進入 STG pod 檢查 kubectl exec -it deployment/strapi-stg -- sh # 檢查編譯後的檔案 ls dist/src/mfa/ # 結果:ls: dist/src/mfa/: No such file or directory # 檢查原始碼 ls src/mfa/ # 結果:ls: src/mfa/: No such file or directory MFA 相關檔案完全不存在於 Pod 中。 甚至連原始碼都沒有被複製進 Docker image。 ...

February 12, 2026 · 3 分鐘 · Peter

Flutter CI/CD Debugging: Three Build Failures in One Day

前言:當建置一直紅燈 CI/CD pipeline 亮紅燈是開發日常,但連續遇到三個不同層面的問題,從 iOS codesigning、Android Gradle、到 Google Play API,這就值得記錄下來了。 這篇文章記錄我在同一天內遇到的三個建置失敗,以及逐步排除的過程。每個問題都有其獨特的根因,但也反映出 CI/CD 環境的複雜性。 問題一:iOS Keychain 解鎖失敗 症狀 Jenkins 建置在 iOS 階段失敗,錯誤訊息: [!] Error unlocking keychain at path: fastlane_keychain Command failed with exit status 51 macOS Keychain 運作機制 在深入問題之前,先了解 macOS Keychain 的運作方式: 關鍵概念: macOS 可以有多個 Keychain,每個都有獨立密碼 憑證必須在「已解鎖」的 Keychain 中才能被 codesign 使用 CI 環境通常會建立專用的 Keychain,避免影響系統 Keychain Fastlane Match 與 Keychain 的互動流程 調查過程 Exit status 51 代表「密碼錯誤」。SSH 進 Jenkins Mac mini 確認: ...

January 17, 2026 · 2 分鐘 · Peter

15 次 Build Failed:一場 Jenkins + Flutter CI/CD 的史詩級除錯之旅

前言:當 Build Failed 成為日常 在過去的 19 個小時裡,我經歷了 15 次 build failed,產生了 15 個 fix commits。如果你覺得這很誇張,讓我告訴你更誇張的:最後一個 bug 是 git describe 在多個 tag 指向同一 commit 時會隨機返回其中一個。 是的,隨機。在 CI/CD Pipeline 裡。 這篇文章完整記錄這場除錯馬拉松,從最初的 Fastlane 版本問題,到 Discord 通知功能的實作與修復,再到 Ruby 相容性地獄,最後揭開 git 鮮為人知的行為。泡杯咖啡,這會是一段旅程。 第一章:Fastlane 與 Bundler 的糾葛 問題 1:Fastlane 版本不一致 Commit: fix(jenkins): use bundle exec for fastlane to ensure version consistency Jenkins 機器上有全域安裝的 Fastlane,但版本與 Gemfile.lock 指定的不同。這導致某些 action 行為不一致。 // Before: 使用全域 fastlane sh 'fastlane ios build' // After: 透過 Bundler 執行,確保版本一致 sh 'bundle exec fastlane ios build' 學習:在 CI 環境中,永遠使用 bundle exec 執行 Ruby 工具,確保版本與 lockfile 一致。 ...

December 21, 2025 · 5 分鐘 · Peter

全端專案 AWS EKS 雲端架構深度解析

前言:從本地開發到雲端生產環境 本文將深入解析一個全端專案在 AWS 上的完整基礎設施架構,展示如何透過 Kubernetes (EKS) 實現高可用性、可擴展性和成本效益的生產環境。這個平台提供線上課程、預約服務、會員管理和金流整合等功能。 本文涵蓋內容: 完整的 AWS EKS 叢集架構 Strapi CMS 和 Vue.js 前端的容器化部署 Jenkins CI/CD 自動化部署流程 Ingress NGINX 負載均衡和 SSL 憑證管理 與 AWS RDS、S3、ECR 的整合 第三方服務整合 (Firebase FCM、台灣金流) 監控與日誌管理 架構概覽 整體架構圖 核心技術棧 基礎設施層: AWS EKS 1.32.9 (Kubernetes 託管服務) AWS EC2 (ARM64 架構 - t4g.medium) AWS RDS PostgreSQL (託管資料庫) AWS S3 (物件儲存) AWS ECR (容器映像倉儲) AWS ELB (負載均衡器) CI/CD 層: Jenkins (Mac mini 本地部署) Docker (容器建置) kubectl (Kubernetes 部署工具) 應用層: ...

June 5, 2024 · 10 分鐘 · Peter