container
container is a tool that you can use to create and run Linux containers as lightweight virtual machines on your Mac. It's written in Swift, and optimized for Apple silicon.
The tool consumes and produces OCI-compatible container images, so you can pull and run images from any standard container registry. You can push images that you build to those registries as well, and run the images in any other OCI-compatible application.
container uses the Containerization Swift package for low-level container, image, and process management.

Run it locally, step by step
You need a Mac with Apple silicon, macOS 15 or newer (26 recommended) and Xcode 26.
Get the code:
git clone https://github.com/Gitguy268/container.git cd containerBuild it:
make allInstall and start it:
sudo make install container system startBoot a Linux VM right in your terminal:
container here ubuntu bashType
exitto leave.
What this fork adds
[!NOTE] This is a community fork of apple/container by Gitguy268. It is not affiliated with or endorsed by Apple Inc. The rest of this README is upstream's, unchanged.
container here |
Runs a container in a VM that lives inside your terminal. No container system start, no background services. Close the tab and the VM is gone. |
container dash |
Full-screen terminal dashboard for containers, images, machines, volumes and networks, with live CPU and memory, shells, logs, start, stop and delete. |
| Linux | The same container commands on any Linux terminal, through podman, including 32-bit x86. See docs/linux.md. |
| Fixes | Terminal output in exec -it / run -it no longer breaks tmux and other TUIs (#2299). Stable environment variable order (#2338). export -o <dir> no longer deletes the directory (#2325). kernel set --force no longer deletes the installed kernel before the copy succeeds (#2326). Relative mount targets are rejected instead of silently mounted at / (#2324). |
| New options | container ls --filter label=k[=v] (#2403), container wait with the exit code kept in inspect (#2402), --pids-limit (#2401), --sysctl (#2400), container system prune (#891), ps alias, CPU % in stats --format json, image snapshots and root filesystems excluded from Time Machine. |
container here: the VM lives in your terminal

container system kernel set --recommended # once; needs the services running for this step only
container system stop # nothing in the background from here on
container here alpine uname -a # boots a VM inside this process
container here ubuntu bash # interactive shell; the tty is detected, no -it needed
echo hi | container here alpine cat # pipes work too
container here alpine sh -c 'exit 3'; echo $? # prints 3
How it works and what it leaves out
Upstream container runs every VM inside launchd services: container-apiserver launches one container-runtime-linux helper per container, and the CLI talks to them over XPC. That is why VMs keep running after you close the terminal, and why nothing works before container system start.
container here skips all of that. It uses the Containerization package directly, in the same way as its cctl run example: the CLI process pulls the image, unpacks it, boots the VM with Virtualization.framework, attaches your terminal (or plain stdio when there is none), waits for the process and removes the VM. To do that, the container binary is signed with the com.apple.security.virtualization entitlement (signing/container-cli.entitlements).
- Lifetime: the VM is stopped and its files are removed when the command ends, when the terminal closes (SIGHUP) or on SIGTERM. If the process is killed with
kill -9, Virtualization.framework stops the VM, and the nextcontainer hereremoves the leftover files. - Ctrl-C: with a tty it goes to the program in the VM, just like
container run -it. Without a tty it is forwarded as SIGINT. - Storage: images live in their own store under
~/Library/Application Support/com.apple.container/here, excluded from Time Machine, so it never writes at the same time as the API server. Images you pulled withcontainer image pullare pulled again the first time. - Network: each run gets its own vmnet NAT network, with DNS through the gateway.
- Not supported: port publishing (
-p), named volumes, private registries,container ls/dashlisting ofhereVMs.
container dash

↑↓/jk select · tab switch · s start/stop · r restart · e shell · l logs · d delete (asks first) · / filter · S system start · ? help · q quit
Build this fork
# Clone it outside Documents and Desktop (vmnet bug)
git clone https://github.com/Gitguy268/container.git && cd container
make all # builds and signs into ./bin and ./libexec
bin/container system start
bin/container here alpine echo hello
CommandLineTools is enough to build. To run the unit tests with only CommandLineTools installed, point the compiler at the Swift Testing macro plugin:
make test SWIFT_CONFIGURATION_EXTRA="-Xswiftc -plugin-path -Xswiftc /Library/Developer/CommandLineTools/usr/lib/swift/host/plugins/testing"
Get started
Requirements
You need a Mac with Apple silicon to run container. To build it, see the BUILDING document.
container is supported on macOS 26, since it takes advantage of new features and enhancements to virtualization and networking in this release. We do not support older versions of macOS and the container maintainers typically will not address issues that cannot be reproduced on macOS 26.
Initial install
Download the latest signed installer package for container from the GitHub release page.
To install the tool, double-click the package file and follow the instructions. Enter your administrator password when prompted, to give the installer permission to place the installed files under /usr/local.
Start the system service with:
container system start
Run your first container
container run --rm alpine echo hello
This pulls the alpine image, runs it in a lightweight Linux VM, prints hello, and
removes the container when it exits. See the tutorial
for a fuller walkthrough that builds and publishes an image of your own.
Upgrade or downgrade
For both upgrading and downgrading, you can manually download and install the signed installer package by following the steps from initial install or use the update-container.sh script (installed to /usr/local/bin).
If you're upgrading or downgrading, you must stop your existing container:
container system stop
To upgrade to the latest release, simply run the command below:
/usr/local/bin/update-container.sh
To downgrade, you must uninstall your existing container (the -k flag keeps your user data, while -d removes it):
/usr/local/bin/uninstall-container.sh -k
/usr/local/bin/update-container.sh -v 0.3.0
Start the system service with:
container system start
Uninstall
Use the uninstall-container.sh script (installed to /usr/local/bin) to remove container from your system. To remove your user data along with the tool, run:
/usr/local/bin/uninstall-container.sh -d
To retain your user data so that it is available should you reinstall later, run:
/usr/local/bin/uninstall-container.sh -k
Next steps
- Take a guided tour of
containerby building, running, and publishing a simple web server image. - Learn how to use various
containerfeatures. - Read a brief description and technical overview of
container. - Browse the full command reference.
- Build and run
containeron your own development system. - View the project API documentation.
Contributing
Contributions to container are welcome and encouraged. Please see our main contributing guide for more information.
Project Status
The container project is under active development. Its release versions are product versions, not semantic versions.
The container CLI compatibility generally preserves backward compatibility within a major release (not breaking existing scripts), however, there may be the odd case where breaking compatibility may be necessary. Note: Features marked experimental (for example, the k8s subcommand) may change and do not guarantee backward compatibility.
The container-apiserver XPC API compatibility preserves forward and backward compatibility within a major version.
Other non-public XPC helpers do not guarantee CLI or API compatibility across different versions.
The container application data provides forward compatibility only, guaranteed within one major version. Upgrading to a newer major version may require a specific upgrade path.