解決 Strapi CMS 正式環境空白頁的踩坑經驗分享

前言:一個簡單的環境變數引發的災難 在部署 Strapi CMS 到 Kubernetes 正式環境時,只是加了一行看似無害的環境變數設定: env: - name: NODE_ENV value: production # 就是這一行! 結果卻導致整個管理後台變成一片空白,連登入頁面都看不到。更詭異的是: ✅ API 完全正常,GraphQL 和 REST 都能回應 ✅ Pod 狀態正常,沒有任何錯誤訊息 ✅ 日誌顯示 Strapi 成功啟動 ❌ 瀏覽器打開 /admin 卻是一片空白 這種「Schrodinger 的服務」(同時正常又不正常)讓人抓狂。經過一番排查,終於發現罪魁禍首是 CSP (Content Security Policy) 在作怪。 本文將深入探討: 為什麼正式環境會出現空白頁 CSP 的工作原理與安全機制 完整的問題排查步驟 如何正確配置 Strapi 的安全策略 生產環境的安全最佳實踐 問題背景:開發正常,正式環境空白 環境差異對比 問題現象詳細描述 Kubernetes Deployment 設定: apiVersion: apps/v1 kind: Deployment metadata: name: strapi-prod namespace: default spec: replicas: 1 selector: matchLabels: app: strapi template: metadata: labels: app: strapi spec: containers: - name: strapi image: myregistry.com/strapi:v5.0.0 env: - name: NODE_ENV value: production # 問題的起點 - name: DATABASE_HOST valueFrom: secretKeyRef: name: strapi-db-secret key: host - name: ADMIN_JWT_SECRET valueFrom: secretKeyRef: name: strapi-admin-secret key: jwt-secret ports: - containerPort: 1337 部署後的症狀: ...

May 7, 2025 · 8 分鐘 · Peter

解決 Kubernetes 多餘 Pod 問題與 CrashLoopBackOff 的實戰心得

前言:一次神秘的 Pod 複製事件 在一次例行的 Strapi CMS 更新部署到 AWS EKS 時,遇到了一個詭異的現象:明明 Deployment 設定檔中清楚寫著 replicas: 1,但實際運行的 Pod 卻有兩個!更奇怪的是,其中一個 Pod 持續處於 CrashLoopBackOff 狀態,而另一個則正常運行。 無論怎麼刪除多餘的 Pod,它總是會像打不死的蟑螂一樣再次出現。這種「靈異事件」讓我開始懷疑 Kubernetes 是不是有自己的想法… 本文將深入探討: 為什麼會出現多餘的 Pod CrashLoopBackOff 背後的機制 Kubernetes Deployment 和 ReplicaSet 的運作原理 實戰排查步驟與解決方案 Secret 編碼陷阱與預防措施 問題背景:Deployment 說一個,實際卻有兩個 問題現象 預期行為: # my-strapi-prod-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-strapi-prod spec: replicas: 1 # 只要 1 個 Pod selector: matchLabels: app: my-strapi-prod 實際情況: $ kubectl get pods -n default | grep my-strapi-prod NAME READY STATUS RESTARTS AGE my-strapi-prod-7d4b5c8f9d-x2k4p 1/1 Running 0 10m my-strapi-prod-8c9a6d7e5f-w8n2q 0/1 CrashLoopBackOff 5 5m 兩個 Pod 同時存在,卻只有一個正常運行! ...

May 6, 2025 · 8 分鐘 · Peter

Strapi 5

客製化UI & Components Strapi 5 客製化UI & Components 發現: https://design-system.strapi.io/?path=/docs/getting-started-welcome–docs 在@strapi/design-system, 目前無法更改底層 https://docs.strapi.io/dev-docs/customization “Some parts of the admin panel can be customized.” 覆蓋樣式:使用自定義 CSS 或樣式覆蓋,而非直接改動源碼。(目前朝此方向研究)

January 15, 2025 · 1 分鐘 · Peter

Strapi 自訂搜尋功能:讓 Admin 面板支援多欄位搜尋

前言 在開發 Strapi 後台管理系統時,我遇到一個實際的使用者體驗問題:在「已購買課程」列表中,管理員可以用「真實姓名」搜尋到用戶的購課記錄,但用「電話號碼」卻搜尋不到。這個不一致的行為讓管理員感到困惑。 本文將分享如何在 Strapi v5 中實作自訂搜尋邏輯,讓 Admin 面板支援跨關聯的多欄位搜尋。 問題場景 資料結構: purchased-course(已購買課程):關聯到 user user(用戶):包含 email、realName、phoneNumber、username、nickname 等欄位 問題現象: ✅ 搜尋「真實姓名」→ 可以找到對應的購課記錄 ❌ 搜尋「電話號碼」→ 找不到任何結果 為什麼會這樣? 因為 Strapi 預設的搜尋功能只會搜尋當前 Collection 的直接欄位,不會自動搜尋關聯表(relation)的欄位。當我們在 purchased-course 列表搜尋時,Strapi 只會在 purchased-course 本身的欄位中搜尋,而不會去搜尋關聯的 user 資料。 解決方案架構 Strapi 提供了三個層級可以自訂搜尋邏輯: 1. Controller 層(API 端點) 位置: src/api/purchased-course/controllers/purchased-course.ts 用途: 處理前端透過 REST API 的搜尋請求 2. Service 層(業務邏輯) 位置: src/api/purchased-course/services/purchased-course.ts 用途: 封裝可重複使用的業務邏輯 3. Content Manager Plugin Extension(Admin 面板) 位置: src/extensions/content-manager/strapi-server.ts 用途: 最重要! 這是讓 Admin 面板搜尋生效的關鍵 ...

October 27, 2024 · 5 分鐘 · Peter

EKS Pod 卡在 Pending?從 Too Many Pods 到 ENI / CNI 限制全面解析

前言:一個讓人懷疑人生的 Pending 狀態 最近部署 Strapi CMS 到 AWS EKS 時,遇到一個詭異的情況: $ kubectl get pods -n default NAME READY STATUS RESTARTS AGE mycompany-strapi-prod-695854fbd4-dzw66 0/1 Pending 0 3h42m 一個 Pod 卡在 Pending 狀態超過三小時,CPU 和 Memory 明明還很充足,但就是起不來。 如果你曾經盯著 kubectl get pods 看著那個永遠不會變成 Running 的 Pending 狀態,同時懷疑是不是 Kubernetes 在跟你開玩笑——恭喜你,你不孤單。 在嘗試了 Google 前五個搜尋結果、檢查了三次 YAML 設定、並認真考慮是否該轉行當咖啡師之後,我終於找到了問題的根源… ⚠️ 劇透警告:問題的根源不是 CPU、不是 Memory,而是一個你可能從沒注意過的限制——網卡(ENI)和 IP 數量。 問題診斷:一步步找出真兇 Step 1:查看 Pod 事件 遇到 Pending 狀態,第一步當然是看看 Kubernetes 到底在抱怨什麼: $ kubectl describe pod mycompany-strapi-prod-695854fbd4-dzw66 -n default 輸出內容很長,但最重要的是 Events 區塊: ...

June 15, 2024 · 10 分鐘 · 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

解決 API 回應中的 BOM (Byte-Order Mark) 字元問題

問題背景 最近在開發過程中遇到一個詭異的問題:呼叫某個 API 後,某個常數 name 的值居然是 nil,但從 raw data 看起來明明有值。 症狀檢查清單: ✅ Console 印出 raw data 看起來正常 ✅ jsonDecode 解碼成功 ✅ Enum 對應的 JSON key (_Name_Ch) 完全相同 ✅ 瀏覽器中直接訪問 API,name 確實有值 ❌ Swift 中取得的 name 卻是 nil 經過反覆檢查,終於發現問題根源:不可見的 BOM (Byte-Order Mark) 字元。 什麼是 BOM? BOM (Byte-Order Mark),中文稱為位元組順序記號,是一個不可見的 Unicode 字元,用於標示文字檔的編碼位元組順序。 常見的 BOM 字元: UTF-8 BOM: 0xEF 0xBB 0xBF (Unicode: U+FEFF) UTF-16 BE BOM: 0xFE 0xFF UTF-16 LE BOM: 0xFF 0xFE 問題診斷 根據問題分析,name 為 nil 的原因是: ...

May 15, 2024 · 3 分鐘 · Peter

關於顏色: Xcode中使用顏色樣本

要叫出如下顏色樣本(swatch) 關於顏色: Xcode中使用顏色樣本 要叫出如下顏色樣本(swatch) var color = #colorLiteral(red: 0.3, blue: 0.2, green: 0.1, alpha: 1.0)打完如以上程式後按下enter 等於的後面就會自動轉成色塊 參考: https://forums.developer.apple.com/forums/thread/690619

April 10, 2024 · 1 分鐘 · Peter

在MAC上消除 ^M 字符

windows 傳檔案/程式 給Mac後, 在行尾的地方都會出現^M字符 導致git status都會出現被modify的狀態 在MAC上消除 ^M 字符 windows 傳檔案/程式 給Mac後, 在行尾的地方都會出現^M字符 導致git status都會出現被modify的狀態 GPT詠唱: **To restore all files in git repo to their state in the last commit **後出現 方法之一**: $git restore — source=HEAD — staged — worktree — .** 解釋: 這個指令是使用 Git 命令行工具中的 “git restore” 命令。它的作用是將工作目錄中的檔案恢復到先前的狀態,並且可以選擇性地恢復到不同的地方。這句指令的意思如下: --source=HEAD: 指定恢復的來源是最新的提交(HEAD),即恢復到最近一次的提交狀態。 --staged: 將檔案的狀態恢復到暫存區(即將已經 “git add” 到暫存區的檔案恢復到暫存區的狀態)。 --worktree: 將檔案的實際內容恢復到工作目錄中,即恢復檔案的內容到實際修改之前的狀態。 .: 指定要恢復的檔案或目錄。在這裡的 . 代表當前目錄下的所有檔案。 總的來說,這個指令的作用是將暫存區中的檔案以及工作目錄中的檔案恢復到最近一次提交的狀態,並且將其內容恢復到修改之前的狀態。 目前感覺最好用….(?)

February 23, 2024 · 1 分鐘 · Peter

從MAC移除 FortiClient.app

在終端機下兩行指令搞定FortiClient.app被鎖住不能移除的問題 從MAC移除 FortiClient.app 在終端機下兩行指令搞定FortiClient.app被鎖住不能移除的問題 # 第一步 /bin/ls -dleO@ /Applications/FortiClient.app # 第二步 sudo /usr/bin/chflags -R noschg /Applications/FortiClient.app執行完上面的指令後,小鎖就不見了 然後就可以用AppCleaner把App完整刪除. 這兩個命令的目的是在Unix/Linux系統中設置和查看文件或目錄的標誌(flags)。其中,chflags命令用於更改標誌,而ls命令則用於列出文件或目錄的詳細信息,包括標誌。 /Applications/FortiClient.app上的小鎖可能是由於該應用程序被設置為“不可更改”(immutable)的屬性,這是一種特殊的標誌。執行chflags -R noschg /Applications/FortiClient.app命令後,將這個“不可更改”標誌移除了,因此小鎖消失了。 通常情況下,應用程序的小鎖表示這個應用程序的文件或目錄具有某種特殊的權限或屬性,可能是為了保護或限制對應用程序的修改。當您使用chflags命令修改了應用程序的標誌後,小鎖就消失了,這表明相關的權限或屬性已經被修改或移除了。 第一行指令的含義: /bin/ls -dleO@ /Applications/FortiClient.app /bin/ls:是列出目錄內容的命令,/bin是ls命令所在的路徑。 -dleO@:是命令的選項或參數,它們分別具有以下含義: -d:指定了要列出的目錄的詳細信息,而不是目錄內容的詳細信息。 -l:以長格式(long format)顯示文件的詳細信息,包括文件類型、權限、所有者、群組、大小、修改日期等。 -e:顯示Access Control List (ACL) 的相關信息。 -O:顯示擴展屬性(extended attributes)的相關信息。 @:顯示文件的扩展屬性,這在macOS中通常與App Store中的應用程序相關。 /Applications/FortiClient.app:是指定的文件或目錄的路徑,這裡是指定了FortiClient應用程序的路徑。 第二行指令的含義: sudo /usr/bin/chflags -R noschg /Applications/FortiClient.app sudo:用於以超級用戶權限執行命令,通常用於需要特權權限的操作。 /usr/bin/chflags:是用於更改文件或目錄標誌的命令,/usr/bin是chflags命令所在的路徑。 -R:表示遞歸地(recursive)應用這個操作到指定目錄及其所有子目錄和文件。 noschg:是要設置的標誌,noschg表示“不可更改”(no change),這意味著對指定的文件或目錄禁止了修改或刪除的操作。 /Applications/FortiClient.app:是指定的文件或目錄的路徑,這裡是指定了FortiClient應用程序的路徑。

February 15, 2024 · 1 分鐘 · Peter