Container machine:在 Mac 上运行持久化的 Linux 环境
WWDC 期间,Apple 的 container 工具迎来了 1.0,而其重磅特性填补了 Mac 开发者多年来一直绕道解决的一个空白:container machine,一个表现得像 macOS 一部分的持久化 Linux 环境。2 介绍它的 WWDC 专题把卖点浓缩成一句话:”Container machine 像容器一样快速轻量,又像虚拟机一样持久。”1 您的仓库和 dotfiles 在两端都可用,登录用户与您的 Mac 账户一致,机器在会话之间保留其文件系统,因此您周二搭好的 Linux 工具链,到周五依然在那里。3
专题 389,”探索 container machine”。
太长不看
container machine随container1.0.0 一同发布,于 WWDC 期间在 GitHub 上线。它在 Apple 于 WWDC 2025 开源的 Containerization 框架之上,提供”具有紧密主机集成的长生命周期 Linux 环境”。2- 容器”以应用程序为模型”,而 container machine”以 Linux 环境为模型”:它运行镜像自身的 init 系统,持久化文件系统的更改,并从标准 OCI 镜像创建。3
- 主机集成是关键区别所在。Linux 登录用户与您的 Mac 账户一致,拥有免密码的
sudo,您的主目录被挂载进机器内部,4 而交互式 shell 会把您带入与您在 macOS 上所在位置相同的工作目录。1 - 完整的子命令集为
create、run、list、inspect、set、set-default、logs、stop和delete,并以m作为简写别名。4 - 1.0 版本还带来了一项值得在升级前知晓的破坏性变更:位于
~/.config/container/config.toml的 TOML 配置文件取代了原先基于 UserDefaults 的系统属性,container system property子命令也随之移除。2
一个 Linux 环境,而非应用程序沙盒
Apple 的文档把界限划得很清楚:”容器通常以应用程序为模型。Container machine 则以 Linux 环境为模型。”3 这种区别体现在三种行为上。Container machine 运行镜像自身的 init 系统,例如 systemd 或 openrc,因此您可以注册长期运行的服务,并在真实的进程管理器下测试您的应用程序:systemctl start postgresql 的工作方式与在一台 Linux 机器上别无二致。3 它会持久化修改,因此您安装的工具会随时间累积,而不会随进程消失。1 它还从容器所用的同一批 OCI 镜像启动,于是您用 container build 构建的镜像同时也是机器的起点。1
落实这一特性的 pull request 把动机说得很直白:container 在临时虚拟机中运行每个工作负载,因此在 1.0 之前,并没有内置的方式来保留一个您可以登录并在其中工作的持久化 Linux 环境。4 在底层,每个 container machine 仍然享有 Containerization 的待遇:拥有自己的轻量级虚拟机,具备基于 VM 的隔离,以及该框架所围绕构建的亚秒级启动时间。1
专题以工作流的视角阐述了设计目标:在 macOS 与 Linux 之间切换应当轻松,环境应当能快速创建,而且”快速创建让多个项目各自拥有专属环境,无需担心依赖或工具链冲突”。1 每个目标发行版对应一台机器是一种预期的使用模式,每台机器都能看到您 Mac 上相同的主目录和 dotfiles。3
循环:在 Mac 上编辑,在 Linux 内构建
专题演示的是一个 Vapor Web 服务器,而它所走通的工作流正是重点所在。1 项目在 macOS 上的 Xcode 中编辑。构建和运行则发生在安装了 Swift 工具链的 container machine 内部。Mac 上的 Safari 通过 IP 地址和端口加载运行中的服务器。当演示者在 Mac 上用 Icon Composer 重新导出一个应用图标并覆盖该文件时,刷新一下浏览器就显示出新的素材,无需任何复制步骤,因为机器和 Mac 共享同一批文件。1
Apple 的文档把这种模式推而广之:您的仓库位于 macOS 上的 $HOME 中,并被挂载进机器内部,因此 macOS 原生工具(性能分析器、浏览器、GUI 调试器)看到的文件,与 Linux 环境看到的是同一批。正如文档所言,在”我构建好了”与”我正在检查它”之间没有复制步骤。3
主机集成比共享挂载更深入。机器会自动创建一个与您 Mac 用户名一致的 Linux 用户,授予其免密码的 sudo,并镜像您当前的工作目录,于是 whoami 和 pwd 在机器内外给出相同的答案。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
管理用的是熟悉的那些动词:ls、inspect、logs、stop 和 rm,其中删除一台机器也会一并移除其持久化存储。3 资源可在创建之后通过 container machine set -n dev cpus=4 memory=8G 调整,于下一次停止再启动时生效;内存默认为主机内存的一半,主目录挂载可以是 rw(默认)、ro 或 none。3 每条命令同样接受 m 作为别名,因此 m run 和 m 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_USER、CONTAINER_UID、CONTAINER_GID、CONTAINER_HOME 和 CONTAINER_MACHINE_ID,于是组织可以把自己的用户设置编码进一个共享的基础镜像中。3
1.0 的其余内容,包括破坏性变更
机器特性是这次发布的头条,但 1.0 也带来了影响现有用户的变更。2
破坏性的那项是配置。一个 TOML 文件取代了基于 UserDefaults 的系统属性,container system property get 和 set 子命令被移除。2 服务在启动时读取 ~/.config/container/config.toml,采用首个匹配优先的优先级(先是您的用户文件,然后是随软件包安装附带的可选文件,最后是硬编码的默认值),更改需要重启服务才能生效。6
提升体验的新增内容包括:用于复制文件的 container cp 命令、container run 上的 --stop-signal 选项,以及为 ls 和 inspect 命令在容器、镜像、网络和卷之间整理过的结构化输出(JSON、YAML、TOML)。2 网络方面有一项正确性修复,利用 XPC 连接作为租约来杜绝 IP 地址泄漏。2 与版本 0 XPC API 的兼容性被移除,承诺在后续版本中提供带版本号的 API。2
要求与 0.x 系列保持一致:一台搭载 Apple silicon、运行 macOS 26 的 Mac。维护者表示,他们通常不会处理无法在 macOS 26 上复现的问题。5
为什么 agent 工作流应当关注
这是我个人立场上的解读,而非 Apple 的主张:container machine 正是编程 agent 所期望的环境形态。运行在 Mac 上的 agent 需要某个地方来执行构建、运行服务器、安装依赖,同时不触碰主机:创建迅速、由真实的 VM 边界隔离、足够持久,使得某一会话中安装的工具链能延续到下一会话。在此之前,Mac 上的答案要么是 Docker Desktop 式的虚拟机(笨重、一个庞大的共享环境),要么是临时容器(隔离但健忘)。每个项目一台机器、从带版本号的 OCI 镜像创建、把仓库挂载进来、内部带免密码的 sudo,这与 agent 沙盒在 Linux 主机上的既有工作方式如出一辙。
同样的特性也服务于普通的跨平台工作。服务端 Swift 是显而易见的受益者:专题演示用的是 Vapor,而 Foundation Models 框架将于今夏开源并支持 Linux,于是”我的 Swift 代码能在 Ubuntu 上跑吗”这一问题的测试环境,如今只差一句 container machine create。任何用过 Windows 的人都会联想到 WSL,而集成的方向是一致的:一个真正的 Linux 内核近在咫尺,文件在两端都可见。Apple 的版本则已经自带了一套基于镜像的工作流。
FAQ
什么是 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 工作负载是临时的、以进程为中心的。而机器是有状态的,运行 systemd 或 openrc,意在随时间被反复使用,就像一台具备容器创建速度的虚拟机。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 作为跨平台与 agent 式开发的认真归宿。在 Mac 上用 MLX 运行 Agentic AI 涵盖了这个故事中模型服务的那一半,而 Swift 新特性(2026) 涵盖了让 Swift-on-Linux 成为一等目标的语言工作。完整的系列汇总页是 Apple 生态系统系列。
参考资料
-
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
unameDarwin/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). ↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
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 propertygetandsetsubcommands, with a linked migration tutorial), thecontainer cpcommand, the--stop-signaloption, the structured output cleanup forlsandinspectacross 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. ↩↩↩↩↩↩↩↩↩↩↩↩ -
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 postgresqlexample, the edit-on-Mac/build-inside workflow and the no-copy-step framing, the one-machine-per-distro pattern with shared$HOMEand dotfiles, the quickstart commands,runbooting a stopped machine,set-default, the management verbs withrmdeleting persistent storage,setfor cpus/memory taking effect after stop and start, the half-of-host-memory default, therw/ro/nonehome-mount modes, the/sbin/initrequirement for machine images, the Ubuntu 24.04 Dockerfile example, and the/etc/machine/create-user.shfirst-boot hook with itsCONTAINER_USER,CONTAINER_UID,CONTAINER_GID,CONTAINER_HOME, andCONTAINER_MACHINE_IDvariables. ↩↩↩↩↩↩↩↩↩↩↩↩↩↩ -
Apple, pull request #1662: Add
container machinefor 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 passwordlesssudo, the home directory mount, the machine keeping its filesystem and running the image’s own init system such assystemdoropenrc, the full subcommand list (create,run,list/ls,inspect,set,set-default,logs,stop,delete/rm), and themalias. ↩↩↩↩↩ -
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. ↩↩↩
-
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. ↩