← 所有文章

Container Machine:在 Mac 上打造持久的 Linux 環境

Apple 的 container 工具在 WWDC 週期間推進到 1.0,而最受矚目的功能正好填補了 Mac 開發者多年來一直想方設法繞過的缺口:container machine,一個行為宛如 macOS 一部分的持久 Linux 環境。2 介紹這項功能的 WWDC 議程,將賣點濃縮成一句話:「Container machine 像容器一樣快速輕量,又像虛擬機一樣持久。」1 您的儲存庫與 dotfiles 在兩端都能取用,登入使用者與您的 Mac 帳號一致,而且機器會在不同工作階段之間保留其檔案系統,因此您週二設定好的 Linux 工具鏈,到了週五依然還在。3

Watch on Apple Developer ↗

第 389 場議程,「Discover container machines」。

TL;DR

  • container machinecontainer 1.0.0 推出,在 WWDC 週期間發佈於 GitHub。它建立在 Apple 於 WWDC 2025 開源的 Containerization 框架之上,提供「具備緊密主機整合的長壽命 Linux 環境」。2
  • 容器是「以應用程式為模型」,而 container machine 則是「以 Linux 環境為模型」:它執行映像檔本身的 init 系統、持久保存檔案系統變更,並由標準 OCI 映像檔建立。3
  • 主機整合是它的差異化所在。Linux 登入使用者與您的 Mac 帳號一致,並具備免密碼的 sudo,您的家目錄也掛載在機器內部,4 而互動式 shell 會讓您直接進入剛才在 macOS 所在的同一個工作目錄。1
  • 完整的子指令集為 createrunlistinspectsetset-defaultlogsstopdelete,並以 m 作為簡短別名。4
  • 1.0 版本也帶來一項值得在升級前知曉的重大變更:位於 ~/.config/container/config.toml 的 TOML 設定檔取代了原本由 UserDefaults 支撐的系統屬性,而 container system property 子指令也已移除。2

一個 Linux 環境,而非應用程式沙箱

Apple 的文件把界線畫得相當精確:「容器通常以應用程式為模型。Container machine 則以 Linux 環境為模型。」3 這項區別展現在三種行為上。Container machine 會執行映像檔本身的 init 系統,例如 systemdopenrc,因此您可以註冊長時間執行的服務,並在真正的行程監督者底下測試您的應用程式:systemctl start postgresql 的運作方式就和在 Linux 主機上一樣。3 它會持久保存修改,因此您安裝的工具會隨時間累積,而不會隨著行程一同消失。1 而且它由容器所使用的同一批 OCI 映像檔啟動,因此您以 container build 建構的映像檔,也能同時作為機器的起點。1

促成這項功能落地的 pull request 直白地說明了動機:container 會在短暫的 VM 中執行每個工作負載,因此在 1.0 之前並沒有內建方式可以保留一個您能登入並在其中工作的持久 Linux 環境。4 在底層,每個 container machine 仍然享有 Containerization 的處理:擁有自己的輕量虛擬機、具備以 VM 為基礎的隔離,以及該框架原本就圍繞著打造的次秒級啟動時間。1

該議程以工作流程的角度勾勒出設計目標:在 macOS 與 Linux 之間切換應該很容易,環境應該能快速建立,而且「快速建立讓多個專案得以擁有各自專屬的環境,無須擔心相依套件或工具鏈相互衝突」。1 每個目標發行版對應一台機器是預期中的模式,而每台機器都會看見來自您 Mac 的同一個家目錄與 dotfiles。3

工作循環:在 Mac 上編輯,在 Linux 內部建構

該議程的示範是一個 Vapor 網頁伺服器,而它所演練的工作流程正是重點所在。1 專案在 macOS 的 Xcode 中編輯。建構與執行則在安裝了 Swift 工具鏈的 container machine 內部進行。Mac 上的 Safari 透過 IP 位址與連接埠載入執行中的伺服器。當講者在 Mac 上以 Icon Composer 重新匯出一個應用程式圖示並覆寫該檔案時,瀏覽器重新整理後就會顯示新的素材,無須任何複製步驟,因為機器與 Mac 共用相同的檔案。1

Apple 的文件將這個模式一般化:您的儲存庫位於 macOS 上的 $HOME,並掛載在機器內部,因此 macOS 原生的工具(效能分析器、瀏覽器、GUI 除錯器)所看到的,與 Linux 環境所看到的是同一批檔案。如文件所言,在「我建好了」與「我正在檢查它」之間並不存在複製步驟。3

主機整合的深度遠不止於共用掛載。機器會自動建立一個與您 Mac 使用者名稱相符的 Linux 使用者、授予其免密碼的 sudo,並鏡像您目前的工作目錄,因此 whoamipwd 在機器內外給出的答案相同。1 唯一會改變答案的指令是 uname:在 Mac 上是 Darwin,在機器中則是 Linux。1

有一項首日就會遇到的摩擦值得在碰上之前先知道:container machine 擁有獨立的網路,而議程明確指出,機器內部的伺服器必須先監聽對外介面,Mac 上的瀏覽器才能連到它。1 示範以您也會採用的方式處理它:container machine list 會在每台機器的名稱與資源旁顯示其 IP 位址,伺服器設定綁定到該位址,接著 Safari 便能透過機器的 IP 與連接埠連到應用程式。1 在任何要從機器對外提供流量的工作流程中,都請預先把這個 IP 位址步驟納入規劃。

各項指令

快速上手只需四行:3

container machine create alpine:latest --name dev
container machine run -n dev whoami       # your host username, not root
container machine run -n dev pwd          # your Mac home directory, mounted in
container machine run -n dev              # interactive shell

container machine run 身兼兩職:帶上指令時,它執行一次後便結束;不帶指令時,它會開啟一個互動式 shell;而若機器處於停止狀態,它會先將其啟動。3 設定一台預設機器,即可從每次呼叫中省去 -n 旗標:

container machine set-default dev
container machine run                     # operates on dev

管理操作則是您熟悉的那些動詞:lsinspectlogsstoprm,其中刪除一台機器也會一併移除其持久儲存空間。3 資源可在建立後以 container machine set -n dev cpus=4 memory=8G 調整,並於下一次停止再啟動時生效;記憶體預設為主機記憶體的一半,而家目錄掛載可設為 rw(預設)、ronone3 每個指令也都接受 m 作為別名,因此 m runm ls 同樣可用。4

自備機器映像檔

任何包含 /sbin/init 的 Linux 映像檔都可以作為 container machine 使用。3 Apple 的文件附上了一份完整的 Dockerfile 範例,將 ubuntu:24.04 轉換成一個帶有 systemd、OpenSSH 與常見命令列工具的機器映像檔,並遮罩那些在輕量 VM 內毫無意義的 systemd 單元。3 您以 container build 建構它,再將標籤傳給 container machine create

佈建還留有一個逃生口。在預設情況下,container 會在首次啟動時執行一個內建的設定指令稿來建立相符的使用者。映像檔中位於 /etc/machine/create-user.sh 的可執行檔會取代該指令稿;它會在首次啟動時以 root 身分執行一次,並設定好 CONTAINER_USERCONTAINER_UIDCONTAINER_GIDCONTAINER_HOMECONTAINER_MACHINE_ID,如此一來,組織便能將自己的使用者設定流程編入一個共用的基底映像檔。3

1.0 的其餘內容,包括那項重大變更

機器功能是這次發佈的主角,但 1.0 同時帶來了會影響既有使用者的變更。2

重大變更在於設定。一個 TOML 檔案取代了由 UserDefaults 支撐的系統屬性,而 container system property getset 子指令已被移除。2 服務會在啟動時讀取 ~/.config/container/config.toml,並採取先符合先生效的優先順序(您的使用者檔案,接著是套件安裝隨附的選用檔案,最後是寫死的預設值),而變更需要重新啟動服務才會生效。6

提升使用體驗的新增項目包括:用於複製檔案的 container cp 指令、container run 上的 --stop-signal 選項,以及為 lsinspect 指令跨容器、映像檔、網路與磁碟區整理過的結構化輸出(JSON、YAML、TOML)。2 網路方面則取得一項正確性修正,改以 XPC 連線作為租約來杜絕 IP 位址洩漏。2 與第 0 版 XPC API 的相容性已被移除,並承諾在後續版本中推出帶版本的 API。2

需求條件延續 0.x 系列維持不變:一台搭載 Apple silicon、執行 macOS 26 的 Mac。維護者表示,對於無法在 macOS 26 上重現的問題,他們通常不會處理。5

為何代理工作流程應該在意這件事

以下是出於我的立場的解讀,而非 Apple 的主張:container machine 正是程式撰寫代理所想要的環境樣貌。在 Mac 上執行的代理需要一個地方來執行建構、執行伺服器並安裝相依套件,同時不去碰觸主機:建立要快、由真正的 VM 邊界隔離,並且要持久到足以讓某次工作階段中安裝的工具鏈,得以延續到下一次。在此之前,Mac 上的解法要嘛是 Docker Desktop 式的 VM(笨重、一整個大型共用環境),要嘛是短暫的容器(隔離卻健忘)。每個專案配一台機器、由帶版本的 OCI 映像檔建立、掛入儲存庫並在內部具備免密碼的 sudo,這恰恰契合了代理沙箱在 Linux 主機上既有的運作方式。

同一項特性也服務於單純的跨平台工作。伺服器端的 Swift 是顯而易見的受惠者:該議程的示範就是 Vapor,而 Foundation Models 框架將於今年夏天開源並支援 Linux,因此「我的 Swift 程式碼能否在 Ubuntu 上執行」的測試環境,如今只差一道 container machine create。任何用過 Windows 的人都會聯想到的對照是 WSL,而其整合方向如出一轍:一個 shell 之遙的真正 Linux 核心,檔案在兩端都看得見。Apple 的版本則一登場就已附帶了以映像檔為基礎的工作流程。

常見問題

什麼是 container machine?

Container machine 是 macOS 上的持久 Linux 環境,自 1.0.0 版起作為 Apple 開源 container 工具的一項功能推出。2 它透過 Containerization 框架在自己的輕量虛擬機中執行、由標準 OCI 映像檔啟動、執行映像檔的 init 系統,並在不同工作階段之間持久保存檔案系統變更。1 主機整合會將您的家目錄掛載在內部、讓 Linux 使用者與您的 Mac 帳號相符並具備免密碼的 sudo,並在邊界兩側維持工作目錄的一致。4

它和一般容器有何不同?

Apple 的文件用一句話說明:容器是「以應用程式為模型」,container machine 則是「以 Linux 環境為模型」。3 一般的 container run 工作負載是短暫且以行程為中心的。機器則是有狀態的、執行 systemdopenrc,並且設計用來隨時間反覆造訪,就像一台具備容器建立速度的 VM。1

它需要什麼條件?

一台搭載 Apple silicon、執行 macOS 26 的 Mac,與 container 工具整體的需求相同。5 該工具在 GitHub 上開源,以 Swift 撰寫。5

升級到 1.0 會破壞任何東西嗎?

有一件事:系統設定從由 UserDefaults 支撐的屬性,改為位於 ~/.config/container/config.toml 的 TOML 檔案,而 container system property get/set 子指令已被移除。2 1.0 的發佈說明附上了一份遷移教學的連結。2 與第 0 版 XPC API 的相容性同樣已被移除,若您曾針對該 API 建構用戶端,這一點便至關重要。2


Container machine 嵌入了這屆 WWDC 不斷講述的同一個故事:將 Mac 定位為跨平台與代理式開發的認真歸宿。在 Mac 上以 MLX 執行代理式 AI 涵蓋了這個故事中模型服務的那一半,而 Swift 的新功能(2026) 則涵蓋了讓 Swift-on-Linux 成為一等目標的語言工作。完整系列的中樞是 Apple 生態系列

參考資料


  1. Apple, WWDC 2026 session 389, Discover container machines. Official transcript. Source for the definition (“A Container machine is fast and lightweight, like a container, and persistent like a virtual machine”), the Containerization recap (Swift framework for Linux containers on macOS, VM-based isolation, sub-second start times, open-sourced at WWDC 2025 along with the container tool), the design principles (including “quick creation allows multiple projects to have their own, dedicated environment, without the worry of conflicting dependencies or toolchains”), the OCI image reuse, statefulness, automatic user mapping and working-directory mirroring, the uname Darwin/Linux demo, and the Vapor workflow demo (edit in Xcode on macOS, build and run inside the machine, load from Safari by machine IP, Icon Composer asset update visible without a copy step). 

  2. Apple, container 1.0.0 release notes, GitHub. Source for the 1.0.0 release, the “long-lived Linux environments with tight host integration” description, the breaking TOML configuration change (replacing UserDefaults-backed system properties and removing the container system property get and set subcommands, with a linked migration tutorial), the container cp command, the --stop-signal option, the structured output cleanup for ls and inspect across containers, images, networks, and volumes, the XPC-connection-as-lease fix for IP address leaks, and the removal of version 0 XPC API compatibility with a versioned API promised in a subsequent release. 

  3. Apple, Container machine documentation, apple/container repository. Source for the application-versus-environment framing (“Containers are typically modeled after an application. A container machine is modeled after a Linux environment”), the init-system behavior including the systemctl start postgresql example, the edit-on-Mac/build-inside workflow and the no-copy-step framing, the one-machine-per-distro pattern with shared $HOME and dotfiles, the quickstart commands, run booting a stopped machine, set-default, the management verbs with rm deleting persistent storage, set for cpus/memory taking effect after stop and start, the half-of-host-memory default, the rw/ro/none home-mount modes, the /sbin/init requirement for machine images, the Ubuntu 24.04 Dockerfile example, and the /etc/machine/create-user.sh first-boot hook with its CONTAINER_USER, CONTAINER_UID, CONTAINER_GID, CONTAINER_HOME, and CONTAINER_MACHINE_ID variables. 

  4. Apple, pull request #1662: Add container machine for managing persistent Linux environments, apple/container repository, merged June 8, 2026. Source for the motivation (each workload runs in an ephemeral VM, with no built-in way to keep a persistent Linux environment to log into), the login user matching the host account with passwordless sudo, the home directory mount, the machine keeping its filesystem and running the image’s own init system such as systemd or openrc, the full subcommand list (create, run, list/ls, inspect, set, set-default, logs, stop, delete/rm), and the m alias. 

  5. Apple, container README, GitHub. Source for the requirements (a Mac with Apple silicon; supported on macOS 26, with maintainers typically not addressing issues that cannot be reproduced on macOS 26) and the description of the tool as written in Swift and optimized for Apple silicon. 

  6. Apple, container configuration tutorial, apple/container repository. Source for the configuration file location at ~/.config/container/config.toml, the first-match-wins precedence (user file, then an optional file shipped with the package install, then hardcoded defaults), and the service reading the file once at startup so changes require a restart. 

相關文章

Apple Swift 團隊在 WWDC26 實驗室裡說了什麼

Apple 的 WWDC26 Swift Group Lab 沒有字幕,我們在本機完成轉錄。工程師針對並行處理、~Sendable 與技術藍圖的坦率回答。

4 分鐘閱讀

Swift 的最新進展(2026):WWDC26 更新總覽

來自 WWDC26 的 Swift 6.3 與 6.4:anyAppleOS 可用性、模組選擇器、borrow/mutate 存取器、Iterable 協定、Swift Testing 互通,以及 MLX。

5 分鐘閱讀

工程哲學:Mark Shuttleworth

Mark Shuttleworth 以一個理念打造 Ubuntu——為人而生的 Linux、人人皆可使用的自由軟體——根植於 ubuntu:以人性待人,並按既定時程交付。

5 分鐘閱讀