Docker 官方 image、Alpine、distroless 這幾個選擇撐了容器基底映像檔十年以上,但 2026 年的供應鏈壓力已經開始把這個組合逼到牆角。Chainguard 在 9 月 Assemble 大會上把 Catalog 擴到 2200 個以上專案、OS Packages 開放給客戶自建 image factory,背後撐這一整套的是 Wolfi、apko、melange 三個彼此扣在一起的開源專案。它們共同表達的立場很直接:Dockerfile 的 RUN 指令跟隨手裝套件的自由,是換不到供應鏈可信度的。
Wolfi 為什麼稱自己是 undistro
Wolfi 不是「另一個 Alpine」。它自我定位為 undistro——沒有核心、沒有 systemd、沒有 sshd、也沒有 base 之外任何預設打包的通用元件。這個切法讓一個 Wolfi 映像檔的基底通常只落在 3 到 5 MB,直接可跑而不用剝掉任何無關檔案。
跟 Alpine 相比最重要的差別是 libc:Wolfi 走 glibc,Alpine 走 musl。musl 十年來把 Python 打包、Node.js 動態載入、Go cgo 這幾條路上砸出來的坑很多開發者都記得——DNS 解析在 5.4 之前不支援 TCP fallback、大量 wheel 沒有 musl 版而每次都要現場編譯、cgo 動起來就對不上系統 libc。Wolfi 直接把這條路繞開,用 glibc 換一個「本來就應該行」的執行環境。
規模上,Wolfi 目前套件數已經破 2000 個並且還在滾動釋出。每個套件都有獨立版號,不像傳統 distro 綁在 stable 週期上,這對想要跟緊 CVE patch 的服務端來說是不小的優勢。所有 apk 檔案都由 sigstore 簽署,附帶 SPDX 格式的 SBOM,這是 Wolfi 從一開始就內建的東西,不用另外裝掃描器補上。
apko 拆掉 Dockerfile 的兩件事
apko 做的事情簡單但激進:把一個 image 定義成「一份 YAML 清單,裡面列出要放進去的 apk 套件」。整份定義大概長這樣:
1 | contents: |
值得單獨拉出來講的是,apko 明確不支援 RUN 這種東西。這不是設計沒做完,而是刻意的決斷。RUN 在 Dockerfile 裡代表「在某個中間狀態的容器裡執行任意 shell 指令」,這個行為天生非確定性——同一份 Dockerfile 隔一個月建置出來的映像檔幾乎不可能位元對位元一致,因為 apt 套件版本會漂移、時間戳會滾動、DNS 查詢順序都可能改結果。拿掉 RUN 之後,apko 可以保證一句大話:跑第二次得到的映像檔 SHA256 跟第一次完全相同。這對稽核、rollback、release 比對都是實打實的可信度。
另一件事是速度。apko 沒有 container runtime、沒有中間層 cache、也沒有 shell 環境需要初始化。整個 build 動作是「下載 apk、驗簽、解壓、寫進 OCI layout」——毫秒等級。CI 上把 base image build 從幾分鐘壓到幾秒,是很有感的差別。
melange 補上「必須從 source 編」這一段
apko 只組現成 apk,不編東西。當專案自己有 binary、C 擴充或非 Wolfi 官方套件時,就需要 melange 把 source 打成 apk。melange 一樣走 YAML pipeline,把 configure、make、install 這幾個步驟宣告出來,跑完產出的 apk 帶著 sigstore 簽章跟 SBOM。組合的用法通常是:melange 建一顆帶自家程式的 apk,apko 把它跟 Wolfi 基底 apk 拼進最終映像檔。
值得注意的一件事是打包思維的移轉。原本在 Dockerfile 裡「進去多裝一個東西就好」的心態,換到這個模型會變成「先把它做成一顆能發布的套件,再組進映像檔」。這個門檻在專案初期是障礙,但長期看反而拉高了單顆映像檔的品質——每個非官方相依都必須先過 apk 打包這一關,把不清楚的來源、寫死路徑、依賴髒 shell 腳本這些問題在打包階段就攔下來。
跟 distroless 這條老路差在哪
Google 的 distroless 走的是「編一個只留 runtime 的 base image」路線。優點是很小,缺點也直接:沒有 package manager,需要新元件時只能把整條 Dockerfile 從頭改寫;沒有 debug shell,正式環境出事只能重新 build 一個附帶 shell 的分身映像檔 debug;套件版本綁在 Debian slim 的釋出節奏上,跟緊 CVE 的能力受限。
Wolfi + apko 的組合把「minimal」跟「有 package manager」這兩件事同時做到。多要一個套件不是重寫映像檔,是往 apko YAML 加一行 package 名稱。debug 需要 shell 時,暫時組一個帶 busybox 的 debug variant 也是同一份 YAML 改一行的事。Chainguard 自家的 Images 目錄超過八成能做到已知 CVE 為零,就是這種可組合性帶來的結果。
導入前值得先問自己的幾件事
這條路線不是無條件更好,實務上有幾個評估點。第一,團隊願不願意把非 Wolfi 官方套件的 apk 打包當成正式工作項目,還是想繼續用 Dockerfile 隨手裝東西——如果是後者,硬轉會很痛。第二,是不是有法遵需求要 FIPS 140-3 或特定 CVE 追蹤——Chainguard 商業版有針對這塊補 SLA 跟保固,Wolfi 開源版本沒有這層承諾。第三,映像檔基底的變動要能被下游應用接住——glibc 版本、時區資料、憑證儲存位置這些細節跟 Debian slim 或 Alpine 都不完全一樣。
對長期跑在自架伺服器上的服務來說,這個組合最實際的收穫其實是「基底穩定性」。傳統 Ubuntu 或 Debian base 隔幾個月就會冒一批不相關的 CVE 需要處理,光是重 build 一輪就要花不少時間;Wolfi 的最小相依意味著這種週期性 patch 的壓力小得多,長期維運成本明顯有機會下探。建議把導入節奏拆成兩階段:先把非核心服務(監控 sidecar、批次工作、內部工具)換到 Wolfi 基底做為練兵,等 apk 打包流程成熟後再處理主線業務服務。
臺灣中小型企業把服務打包在容器內部署已經是預設做法,映像檔品質直接決定資安稽核的通過難度。NCSE Network 提供的臺灣是方電訊機房 VPS 搭配 Intel Gold CPU 與 NVMe SSD,能撐住容器化服務對 I/O 與網路延遲的要求,7 天免費試用讓團隊有時間評估把基底遷移到 Wolfi 的實際影響;如果正在規劃自建映像檔工廠或整合 CI/CD 流水線,這是把整套環境跑起來的合適起點。