Add container machine for managing persistent Linux environments - #1662
Merged
Conversation
crosbymichael
approved these changes
Jun 8, 2026
egernst
approved these changes
Jun 8, 2026
`container machine` creates and manages container machines: lightweight, persistent, and integrated Linux environments that feel like an extension of your Mac, created from standard OCI images with a familiar UX. Subcommands: create, run, list (ls), inspect, set, set-default, logs, stop, delete (rm). `m` aliases machine. Adds command-reference and how-to docs. Co-authored-by: Jaewon Hur <jaewon_hur@apple.com> Co-authored-by: John Logan <john_logan@apple.com> Co-authored-by: Michael Crosby <michael_crosby@apple.com> Co-authored-by: Eric Ernst <eric_ernst@apple.com> Co-authored-by: Danny Canter <danny_canter@apple.com> Signed-off-by: Raj Aryan Singh <rajaryan_singh@apple.com>
realrajaryan
force-pushed
the
container-machine
branch
from
June 8, 2026 17:40
601c7ec to
f3647ec
Compare
egernst
approved these changes
Jun 8, 2026
Code Coverage
|
container machine for managing persistent Linux VMscontainer machine for managing persistent Linux environments
5 tasks
bevanjkay
pushed a commit
to ascarter/homebrew-core
that referenced
this pull request
Jun 10, 2026
Two related regressions in 1.0.0 prevent `container system start` from completing: 1. The previous formula patched Sources/ContainerPlugin/InstallRoot.swift via `inreplace` to hard-code the keg prefix as the install root. Upstream PR apple/container#1558 (May 2026) renamed the symbols the inreplace targeted (`CommandLine.executablePathUrl` ->`executablePath`, `deletingLastPathComponent` -> `removingLastComponent`), so the substitution silently became a no-op when 1.0.0 was bumped. The apiserver now resolves its install root as the lexical grandparent of the running executable without symlink resolution, which on /opt/homebrew/bin/container lands at /opt/homebrew rather than the keg, where no `libexec/container-plugins` directory exists. The apiserver crash-loops with "cannot find any plugins with type network" and `container system start` hangs at "Testing access to container-apiserver...". Fix this without patching upstream sources by installing the binaries to libexec/ and using `bin.env_script_all_files` to generate shim wrappers in bin/ that `exec` the real binaries via their absolute keg path. The kernel-reported executable path now has `opt_prefix` as its lexical grandparent, putting the plugin search exactly on top of `opt_prefix/libexec/container-plugins/`. The wrappers also export `CONTAINER_INSTALL_ROOT=opt_prefix` for the code paths that honor the environment variable. 2. The 1.0.0 release added a new `machine-apiserver` plugin (apple/container#1662, "container machine") under Sources/Plugins/MachineAPIServer that the formula never picks up. `container system start` fails at the "Verifying machine API server is running" step without it, so it must ship together with fix Homebrew#1 for the start command to succeed at all. Refactor the plugin installation loop to a data-driven structure so adding the new plugin (with its config.toml plus init and create-user.sh resources from Sources/Plugins/MachineAPIServer/Resources/) is a one-line addition. Codesigning mirrors what the upstream Makefile does for that binary (--prefix only, no entitlements; no `signing/machine-apiserver.entitlements` exists upstream). Verified locally with: brew install --build-from-source container brew test container brew audit --strict container container system start container list container machine list
subpop
added a commit
to subpop/applebox
that referenced
this pull request
Jun 17, 2026
Replace the custom PID 1 sleep loop with a multi-mode init script that execs into the distro's real /sbin/init (systemd, OpenRC, etc.). This provides proper zombie reaping, system service support, and correct boot semantics. The init script operates in three modes: - Boot mode (no flags): sets hostname, writes .containerenv, execs /sbin/init - Shell mode (-s): resolves distro-appropriate shell from /etc/passwd with distro-aware fallbacks, execs into login shell or command - User setup mode (-u): creates container user on first entry via direct /etc/passwd manipulation (distro-agnostic, replaces useradd/usermod) User setup is decoupled from boot and runs once on first entry rather than every boot. Shell resolution moves into the container (reading /etc/os-release for distro detection) instead of relying on host-side stamp files. Working directory resolution mirrors the host CWD only when under the user's home directory. Inspired by apple/container#1662 (container machine). Assisted-By: Claude
| let pluginLoader = try initializePluginLoader(log: log) | ||
|
|
||
| try await initializePlugins(pluginLoader: pluginLoader, log: log, routes: &routes) | ||
| try await initializePlugins(pluginLoader: pluginLoader, log: log, routes: &routes, debug: debug) |
|
|
||
| let service = PluginsService(pluginLoader: pluginLoader, log: log) | ||
| try await service.loadAll(bootPlugins) | ||
| try await service.loadAll(bootPlugins, debug: debug) |
7 tasks
jianliang00
pushed a commit
to jianliang00/container
that referenced
this pull request
Aug 28, 2026
## Type of Change
- [ ] Bug fix
- [x] New feature
- [ ] Breaking change
- [ ] Documentation update
## Motivation and Context
`container` runs each workload in an ephemeral VM, so there's no
built-in way to keep a persistent Linux environment you can log into and
work in. `container machine` adds one.
A container machine is a lightweight, persistent, and integrated Linux
environments that feel like an extension of your Mac, created from
standard OCI images with a familiar UX. The login user matches your host
account with passwordless `sudo`, your home directory is mounted inside
the VM, and each machine keeps its filesystem and runs the image's own
init system (such as`systemd` or `openrc`).
```bash
container machine create alpine:3.22 --name my-machine
container machine run -n my-machine # interactive shell
container machine set -n my-machine cpus=4 memory=8G
```
Subcommands: `create`, `run`, `list` (`ls`), `inspect`, `set`,
`set-default`, `logs`, `stop`, `delete` (`rm`); `m` aliases `machine`.
Docs added to `docs/command-reference.md` (Machine Management) and
`docs/how-to.md` ("Use container machines").
## Testing
- [x] Tested locally
- [x] Added/updated tests
- [x] Added/updated docs
Signed-off-by: Raj Aryan Singh <rajaryan_singh@apple.com>
Co-authored-by: Jaewon Hur <jaewon_hur@apple.com>
Co-authored-by: John Logan <john_logan@apple.com>
Co-authored-by: Michael Crosby <michael_crosby@apple.com>
Co-authored-by: Eric Ernst <eric_ernst@apple.com>
Co-authored-by: Danny Canter <danny_canter@apple.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Type of Change
Motivation and Context
containerruns each workload in an ephemeral VM, so there's no built-in way to keep a persistent Linux environment you can log into and work in.container machineadds one.A container machine is a lightweight, persistent, and integrated Linux environments that feel like an extension of your Mac, created from standard OCI images with a familiar UX. The login user matches your host account with passwordless
sudo, your home directory is mounted inside the VM, and each machine keeps its filesystem and runs the image's own init system (such assystemdoropenrc).Subcommands:
create,run,list(ls),inspect,set,set-default,logs,stop,delete(rm);maliasesmachine. Docs added todocs/command-reference.md(Machine Management) anddocs/how-to.md("Use container machines").Testing