發表文章

Docker Bind Mount Permission Denied: UID/GID、Non-root 與 Rootless 的取捨

English Abstract: A classic Docker bind mount failure: the container writes to a host directory and gets Permission denied, even though the host user clearly owns that directory. The root cause is almost always a UID/GID mismatch between the host filesystem and the container process — Linux permission checks only look at numeric IDs, not usernames. This post compares three fixes: pinning the container to a specific UID with --user , the PUID/PGID entrypoint pattern popularized by LinuxServer.io images, and Rootless Docker / Podman's user namespace remapping ( userns-remap ), along with the security and portability trade-offs of each. 用 -v 把 host 目錄掛進 container,裡面的程式想寫入卻得到 Permission denied,即使在 host 上明明對這個目錄有讀寫權限,這是最常見的 bind mount 問題之一。問題幾乎都出在 host 檔案的 owner UID/GID,跟 container 內 process 實際跑的 UID/GID 對不上——Linux 的權限檢查只認數字,不認「使用者名稱」。這篇文章說明三種常見解法:用 --user 直接指定 UID、用 PUID/PGID entrypoint 動態對齊、以及 Rootless Docker/Podman 的 user namespace 重映射,並比較三者在安全性、可攜性與設定複雜度上的取捨。 (一...

Docker Container 錯誤排查指南

English Abstract: When a container exits with code 137 or 143, it's tempting to assume OOM or a clean shutdown — but both assumptions are often wrong. This post walks through reading docker inspect 's ExitCode and OOMKilled fields correctly, decoding the 128+signal exit code convention, cross-checking kernel-level OOM killer logs with dmesg / journalctl , setting sane memory limits, and the classic shell-form vs exec-form CMD pitfall that silently breaks SIGTERM handling. 當 production 裡的某個 container 無預警停掉, docker ps 已經看不到它, docker ps -a 卻顯示 Exited (137),第一個念頭通常是「是不是被 OOM killer 幹掉了」。但 137 不一定代表記憶體不足,143 也不一定代表你自己下了 docker stop 。這篇文章從 docker inspect 的欄位意義開始,拆解 Exit Code 與訊號的對應關係、怎麼用 dmesg / journalctl 找出真正的 OOM killer 記錄,到設定 memory limit 與讓應用程式正確處理 SIGTERM,建立一套完整的排查流程。 (一)用 docker inspect 看懂 ExitCode 與 OOMKilled container 停掉的瞬間, docker ps -a 只能看到一個簡化過的狀態字串,真正有用的欄位要從 docker inspect 的 State 區塊才看得到。先執行: docker inspect <container_id> --format '{{json...

Google Skills 介紹

圖片
過往使用 Google Cloud 遇到問題時的流程是:先搜尋 Google Cloud Documentation,讀完文件、理解產品行為與限制,再自己轉換成 gcloud、kubectl 或 Terraform 指令,最後執行與驗證。這套模式存在了很多年。但隨著 Codex、Claude Code、Gemini CLI 等 Coding Agent 真正進入工程師的 Terminal,一個新的問題逐漸浮現: 如果實際操作 Cloud Infrastructure 的不只工程師,也包含 AI Agent,那麼官方文件是不是也需要一種「給 Agent 使用的版本」? (本文含聯盟連結。As an Amazon Associate I earn from qualifying purchases.) Google 在 Cloud Next 2026 推出的官方 Agent Skills repository: Google Skills ( github.com/google/skills ),正是在回答這個問題。Google 把 Skill 定義為一種為 Agent 提供額外能力與專業知識的開放格式,也把它描述成針對特定技術或任務設計的 agent-first documentation 。 換句話說, 它不是把 Google Cloud Documentation 再複製一次,而是把產品知識重新整理成 AI Agent 可以理解、判斷,並在適當時機使用的操作知識。 (一)從 13 個 Skills 開始 Google Skills 在 2026 年 4 月 Cloud Next 發表時,規模並不大。第一批只有 13 個 Skills: 產品類:AlloyDB、BigQuery、Cloud Run、Cloud SQL、Firebase、Gemini API、Google Kubernetes Engine(GKE) Well-Architected 類:Security、Reliability、Cost Optimization Recipe 類:Google Cloud Onboarding、Authentication、Network Observability Google 當時就表示這個 repository 會持...

灰度發布 (Progressive Delivery / Gradual Rollout) 是什麼?從 Canary、Blue-Green Deployment 到 Feature Flag

圖片
當新的版本服務要上 production 生產環境時,最直覺的做法就是把所有流量一次全部切過去上線,這是時常看到的,這種做法如果順利的話那就皆大歡喜(實際上不太可能),但只要新版本藏了一個沒測到的 critical bug,等於讓 100% 的使用者同時出問題。這種「一次全量發布」在生產環境裡最省事、卻也最危險,在短期快速迭代開發下很難有 100% 沒有任何缺陷的軟體應用服務,但現在還是時常看到不少企業在做這樣的事情。實際上為了控制這個風險,software engineering 圈子早已發展出「灰度發布」這個概念,底下可細分出 Canary Rollout、藍綠部署(Blue-Green Deployment)、A/B Testing、Feature Flag 幾種做法,但這幾個詞常常被混著用、甚至誤用。這系列文章會先在第一篇把名詞和框架釐清,後面幾篇再針對 AWS EKS + Kubernetes 的具體實作、以及 Web 通訊 App(含 WebSocket 長連線、Android/iOS 行動端)的灰度發布細節展開。在往下讀名詞定義之前,先介紹這系列文章會用的範例情境,方便對照後面出現的程式碼與設定。 本系列的範例情境 這系列文章會用一套虛構的雲端 Web 通訊 App (姑且稱它 ChatApp) 當作貫穿全系列的範例,情境設定盡量貼近實際專案常見的架構,方便對照後面出現的程式碼與設定檔。 ChatApp 提供三種客戶端,使用者可以自由選擇任一種登入使用: iOS App (原生 Swift) Android App (原生 Kotlin) 網頁版 (瀏覽器直接使用的 Web App) 三種客戶端底層都呼叫同一組後端 API,後端部署在 AWS EKS(Kubernetes)上,由幾個主要模組組成: Gateway / Ingress 層 :對外的統一入口,也是本文提到的 Canary 流量分流實際作用的地方 訊息服務(Message Service) :處理聊天訊息的收發,跟客戶端之間走 WebSocket 長連線 認證服務(Auth Service) :處理登入、身分驗證 資料庫(Database) :儲存使用者資料與歷史訊息記錄 後面所有的範例(包含 chatapp-v1 / chatapp-v2 、 ...

熱門文章

Docker 環境下的 Proxy 配置