How is this different to bind mounts
Edit: It's a VM per container. https://github.com/apple/container/blob/main/docs/technical-...
UX wise it looks kinda neat though!
I have made it a MCP so that it's easily discoverable by all the coding agents
I would really love if apple could give inexpensive way to run amd64 containers for situations when dev wants to use their own hardware. We've used LIMA for now, was too much of a hussle. But if there's a more native experience – would give it another try.
Which for many folks is good enough for what they are doing, thus the status quo of desktop platforms will hardly change for current form factors.
Discover container machines
I can create docker-images with docker compose, or use something like colima, which this seems to be close to (that should have some advantages over docker, although my hope of circumventing W^X page protection did not pan out).
I was perplexed that the repository does not put these container machines in context. The seem to be close to colima? When should I use which option (docker, collima, container machines ?)
Maybe others wonder too but are ashamed to ask. I have no shame ;)
Thanks for any pointers
I am trying it on but its brekaing on homebrew 1.0.0. The formula puts plugins at opt/container/libexec/container-plugins/ and the apiserver looks in libexec/container/plugins/
This can be solved through a symlink or smth
There's some clever advertising in it for Linux, if Linux was advertising.
In my testing (iirc) filesystem performance was not good enough to be usable with node/rust dev where lots of small files get stat-ed
update: what's new is the `container machine` subcommand. I went to test it out, but container failed to run at all for me: https://github.com/apple/container/issues/1681
BSD actually has this already.
However, unlike Lima, an Apple Container is not a full VM, so you cannot SSH to it, or forward SSH-agent signatures into a machine.
So it's more of a devcontainer story, which is also a great use case. Nice to see Apple creating tooling around their VZ framework.
Edit: referential clarity.
But like having containers that need file watchers like vite dev server, or frankenphp in watch mode will overload OrbStack real quick since It seems to fallback to polling instead of listening to fs events.
So I'm stuck running vite dev servers and the like on the host.
AFAICT it's pretty similar.
The Containerization framework is a library that sits as a layer on top of the virtualization framework. So each container is its own VM.
Machine is tooling above the containerization framework to run multiple things in a container in a vm.
Are you sure about that? A few comments above a commenter states that they don’t run inits at all (because they ran alpine), multiple people replied that it works fine if you give it an image with an init, and they acknowledged their error.
It's a full vm
Proton is based on Wine which translates Windows instructions to Linux.
Besides there's already Wine for mac.
But I would love to be wrong here.
Why would any serious developer use closed-source code they can't debug and modify? Especially for a production server?
It's the same reason no serious developers or hackers use macOS, like part of the point of being a developer is being able to dig into the code at any layer and debug and fix things.
If they were to support darwin containers, what would be the point? Literally nobody would build to it, Linux won.
Blog post soon
Which kernel is running, and is it hosted in hypervisor.framework, as is done with UTM (when not using the qemu mode)?
Our biggest perf/resource gain is dynamic memory, which reduces memory usage a lot by releasing unused memory back to macOS. Nothing else supports this, including Containerization.
I gave Container Machines a try and it seems to be much closer to OCI containers with a default bind mount than OrbStack machines. It has fewer integrations and doesn't run systemd or any other normal init system, so it's hard to run services.
If the guest image has /sbin/init, we use that.
We'd recommend using a base image for the guest that includes systemd. ie: https://github.com/apple/container/blob/main/docs/container-...
Wow, missed this when reviewing OrbStack. I assumed that you just used Containerization and therefore would have the same limitation.
Personally I’d rather the company provisioned me MacBook hardware with Linux. Unless Fable or some other ai ports asahi properly to modern hardware I expect to retire before this is possible, orbstack is the next best thing, available today.
The pain of working around Docker Desktop is bad.
There's also simply the possibility of using linux software directly in macos without doing OS dependent changes to the software.
I know I'm basically taking the bait, but I guess I've not been "seriously" developing stuff for the past decade or two, which is news to me!
That being said, my point isn't that Apple should absolutely focus on making a server OS again. It just saddens me how far behind macOS has fallen as they stopped caring about the fundamentals; back in the day, it would be Linux trailing behind macOS. Nowadays, you can't even have multiple routing tables on the latter, the firewall code was probably last updated in Snow Leopard, and what Apple happily shows off on WWDC is a wrapper around Linux. Something functionally equal can be cobbled up together by anyone sufficiently experienced in minutes, using just Bash, OpenSSH, and QEMU.
I really wish macOS would let me have a similar level of control over applications as Linux with namespaces, without me having to do all the heavy lifting.
because nobody does ci/cd against macOS or iOS apps right?
* need a usb sdcard reader for macbook pro cause the builtin is not usb)
> I gave Container Machines a try and it seems to be much closer to OCI containers with a default bind mount than OrbStack machines. It has fewer integrations and doesn't run systemd or any other normal init system, so it's hard to run services.
The linked md document says:
> Real Linux services for testing. Run a database or whatever your stack needs as a system service — systemctl start postgresql works on images with systemd installed.
Was that not the case when you used container machines?
"Real Linux services for testing. Run a database or whatever your stack needs as a system service — systemctl start postgresql works on images with systemd installed."
I wanted to make its VM/machine our default secure agent sandbox, but I couldn’t figure out how to isolate this VM from the host properly. This thread prompted me to find the issue though, and I saw this was recently implemented! https://github.com/orbstack/orbstack/issues/169
I did an experiment migrating my Podman workload to Apple's container @ https://gist.github.com/jmonster/39e14585e107dbf990a90966c0f...
TL;DR reduces ram/storage usage; minimizes it's existence
I wrote about that angle here: https://igorstechnoclub.com/sandbox-exec/
Feels like the spiritual successor to sandbox-exec, but with VM-level isolation.
I started using Colima a couple of years ago because I got bored of how bad Docker Desktop was and just started using the CLI / the "Services" tool window in whatever Jetbrains IDE I was using at the time anyway. I can't see myself moving away from it any time - having multiple profiles is an absolute winner of a feature for me there, but maybe the next time I set up a Mac from scratch I'll have a play with this.
They've now added a WSL-style virtual machine layer, but there's no x86 container story (Apple's killing Rosetta) so I imagine some qemu shimming will be required.
There's still no equivalent to VPNKit or GVisor for networking so you'll be bridging I think. See: https://cacm.acm.org/research/a-decade-of-docker-containers/ for how Docker for Mac does this
I can't spot any support for dynamic memory ballooning to prevent the hypervisor from gobbling up too much memory. We've had this in Xen since forever! https://xenproject.org/blog/ballooning-rebooting-and-the-fea...
And, most obviously: NO SUPPORT FOR MACOS. This is the single feature that only Apple can do, and they're choosing not to implement it deliberately, and it's so stupid given the pains we all have to go through to implement CI for macOS. In the land of OCaml, we were forced to implement a custom ZFS snapshotter to get reasonably cost effective macOS CI for our package repository: https://tarides.com/blog/2023-08-02-obuilder-on-macos/. This was fun to build, but it sucks to have to maintain it.
Also, I'm really curious what the GPU passthrough story here is for LLMs, since the Apple Silicon -> Linux kernel support is gated on Asahi's support, but that's been lagging beyond M2 due to the efforts of reverse engineering.
Do better for your developers, Apple. This is a half-baked sweep across third-party software without addressing the core needs around your own operating system.
Container machine provides a highly integrated Linux environment that works seamlessly on your Mac. Container machines are fast, lightweight and persistent. They are based on standard OCI images that can be built and shared. Host integrations such as automatic user and home directory sharing provide quick and easy access to your Linux environment no matter where you are in a terminal.
Containers are typically modeled after an application. A container machine is modeled after a Linux environment. It runs the image's init system allowing you to register long running services or test your application under a process supervisor. A container machine automatically maps your username and home directory into the Linux environment. Your repositories and dotfiles are available on both platforms. Use editors and tools directly on macOS simultaneously building and running your application inside of the Linux environment.
$HOME on macOS and is mounted at /Users/<username> inside the container machine. Use your macOS editor or IDE; compile and run inside your container machine.systemctl start postgresql works on images with systemd installed.alpine, ubuntu, debian. Each has the same $HOME and the same dotfiles from your Mac. Quickly test your application in various distributions.container machine create alpine:latest --name dev
container machine run -n dev whoami # your host username, not root
container machine run -n dev pwd # /home/<you> — your Mac home dir, mounted in
container machine run -n dev # interactive shell; cd into your repos in $HOME
container machine run is how you get a shell or run a single command. If the container machine is stopped, run boots it first.
With no command, container machine run opens an interactive shell as a user that matches your host account:
container machine run -n dev
Pass a command to run it once and exit:
container machine run -n dev uname -a
container machine run -n dev -- cat /proc/cpuinfo
Pick a default container machine so you can drop the -n flag:
container machine set-default dev
container machine run # operates on dev
container machine ls # list all container machines
container machine inspect dev # JSON detail for one
container machine stop dev # stop the container machine
container machine rm dev # delete, including its persistent storage
container machine has the alias m, so m ls, m run, etc. all work.
container machine set updates configuration on disk. Changes take effect after the next stop and start:
container machine set -n dev cpus=4 memory=8G
container machine stop dev
container machine run -n dev -- nproc
Memory defaults to half of host memory. The home-mount can be rw (default), ro, or none.
Any Linux image that includes /sbin/init works as a container machine. For example, this Dockerfile builds an Ubuntu 24.04 container machine image with systemd and common command-line tools:
FROM ubuntu:24.04
ENV container container
RUN apt-get update && \
apt-get install -y \
dbus systemd openssh-server net-tools iproute2 iputils-ping curl wget vim-tiny man sudo && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
yes | unminimize
RUN >/etc/machine-id
RUN >/var/lib/dbus/machine-id
RUN systemctl set-default multi-user.target
RUN systemctl mask \
dev-hugepages.mount \
sys-fs-fuse-connections.mount \
systemd-update-utmp.service \
systemd-tmpfiles-setup.service \
console-getty.service
RUN systemctl disable \
networkd-dispatcher.service
RUN sed -i -e 's/^AcceptEnv LANG LC_\*$/#AcceptEnv LANG LC_*/' /etc/ssh/sshd_config
Build it and create a container machine from it:
container build -t local/ubuntu-machine:latest .
container machine create local/ubuntu-machine:latest --name ubuntu
By default, container runs a built-in setup script on first boot to provision the user described above. To use your own setup instead, add an executable script at /etc/machine/create-user.sh to the image. It runs once, as root, on first boot, with these variables set:
CONTAINER_GIDCONTAINER_HOMECONTAINER_MACHINE_IDCONTAINER_UIDCONTAINER_USERThat said, colima still has the expensive VM that upthread is mentioning.
LE: nevermind, it is already on MacOS. Did not read everything.
By the way, is it headless or can it run a full Linux desktop? Use case: buy a Mac, uninistall whatever can be uninstalled, run the Linux VM as primary desktop forgetting MacOS and without going through Asahi and the incomplete hardware support.
Apple uses OpenBSD's Packet Filter [1]; I doubt multiple routing tables are a problem. Back in the Snow Leopard days, it was FreeBSD's IPFW, which is also no slouch.
Whatever a firewall can do, PF can do it.
You can also get a nice GUI for PF [2].
"Exploring Darwin and PureDarwin: The Open-Source Foundation of Apple's Operating Systems" - https://machaddr.substack.com/p/exploring-darwin-and-puredar...
> Memory defaults to half of host memory
That's the most expensive part of the whole transaction, b/c AFAIK, RAM is then dedicated to the VM. It can be swapped out, I suppose, but that's not great.
Running VMs is really really easy and low maintenance demand on Apple. And it’s guaranteed compatibility.
Wasn’t compatibility what really sunk WSL1?
Even Microsoft gave up on Windows and just runs Linux most things except niche cases. Heck, even SQL Server which is expensive piece of machinery got ported to Linux and that's the default target now in their docs.
With that said, one can't deny Apple's success on the b2c side of things so it feels wrong to call their strategy a failure.
There aren’t any app developers avoiding the Apple ecosystem because there aren’t Darwin containers. They don’t sell server hardware and by all accounts have no intention of ever reentering that space. So they’d spend a bunch of developer cycles to reduce their own revenue stream with no apparent upside beyond “goodwill” which they’ve never been overly concerned about.
i'd still use less permissive containers for things i don't feel comfortable installing on the host, e.g. npm.
Doesn’t seem to have Compose support though, but it’s probably not impossible to build upon.
And of course, it also uses VMs, though unlike Docker, it’s one (micro-?) VM per container: https://github.com/apple/container/blob/main/docs/technical-...
Yes, but a big part of the problem with WSL1 was the size of the conceptual gap between POSIX and Windows NT that WSL1 had to bridge. An “MSL1” would likely have fewer problems because the gap between macOS and Linux is smaller, given they are both POSIX
The other thing Apple could potentially do, is add Linux-compatible APIs to macOS. IBM wanted to support Kubernetes on their z/OS mainframe operating system, so they implemented on it a clone of Linux namespace APIs, e.g. unshare. Then we could have macOS nodes in a K8S cluster-which might actually be useful for some people, e.g. if you have a Jenkins CI farm, the Linux nodes can run on K8S, but currently macOS nodes (which you need if you are targeting iOS or macOS) can’t, they have to be bare metal or VMs.
More Linux-macOS source compatibility would also benefit macOS by making it less work to port software to it from Linux
Which is why so many projects get burned with their license choices.
[1] https://cheatsheetseries.owasp.org/cheatsheets/Docker_Securi...
And I think I would caution Apple to consider the lessons of WSL; having shared access to the filesystem is just the bare minimum. Next is networking (and god is this a rabbit hole with WSL), people will want to access their USB devices, X forwarding, GPU passthrough..
"bind mounts? I'm better without it"
If they're investing resources into it regardless, they might at least try making something that Docker for macOS and co. haven't solved the same exact way already. Something that, due to their almost unhealthy obsession with "system integrity", only they can realistically make. Like native containers.
Which is a ton of ‘em.
The proton model has the benefit that bugs on linux can be fixed by Valve and the Wine community. While bugs in an official linux port can only be fixed by the game publisher which rarely happened. There also seems to be virtually no downsides to running a Windows game in Proton. These days I don't even bother checking the Wine DB or proton rating because unless the game is deliberately blocking linux via anti cheat, it will just work.
But yeah, I guess my use case is not the main use of such tools or their purpose in general. Thanks for the link, I‘ll take a look at it.
If we wanted access to all interfaces, we'd just run it locally.
We want the container as a closed box, "wasting power doing math", i.e. processing what we actually passed to it.
You still can, and it still works exactly the same way.
(Plus, you could always even have amd64 linux containers on macOS AS, with good performance, via Rosetta2).
This was due to implicitly granting the LLM access to the host docker daemon, which has superuser privileges, not due to a "container breakout". That's arguably a very different scenario, but of course both are worth considering.
> So if you want to use containers for anything but easier development, you need to be much more proficient than the average user already.
I'd disagree. Containers, at least without granting them additional privileges such as CAP_NET_ADMIN and without write-bind-mounting sensitive host directories into the container, offer a reasonable security boundary compared to the counterfactual, despite their bad reputation.
I guess my use case is not that important for the main user of these tools.
Linux will stay forever a headless operating system great for embedded, server rooms and containers.
We have all limited time on Earth, and eventually Valve won't be around as it used to be, might even be acquired, sold, whatever, then what in regards to Linux gaming?
I never want to deal with that again ;)
[edit] fwiw, Termux on Android is similarly a fun pseudo-environment. It's a nice and helpful toy.
Now with the Fex project, it might end up that running Windows games on linux on a modern ARM processor could be the best way to game going forward, especially for mobile platforms like the SteamDeck.
I am convinced that if POSIX subsystem was UNIX serious, GNU/Linux would never taken off on PC, and the whole would be divided between SGI, HP-UX, Solaris, Aix and Windows NT.
The reason Linux grew in the 90s was because it was part of the hacker culture. Not because better options didn’t exist.
Kids liked the fact that Linux was a free-for-all, anything-goes, platform. It wasn’t stuffy like Unix and it wasn’t proprietary like Windows.
Then those kids grew up and became decision makers themselves. And we started to see Linux replace FreeBSD and commercial Unixes.
https://old.reddit.com/r/ProgrammerHumor/comments/96ufiz/pro...
That's handy when you're entering paths in a Cygwin/MSYS Bash shell, but might not help much if you're trying to parse or otherwise work with existing patgh variables composed with backslashes.
There's much more to it than that if you check out the link above. Misconfiguring a container is the 2026 version of misconfiguring FTP and MYSQL in the 90s. I.e. most users don't even know how they are asking to get rooted.
> container runs containers differently. Using the open source Containerization package, it runs a lightweight VM for each container that you create. This approach has the following properties:
> * Security: Each container has the isolation properties of a full VM, using a minimal set of core utilities and dynamic libraries to reduce resource utilization and attack surface.
> * Privacy: When sharing host data using container, you mount only necessary data into each VM. With a shared VM, you need to mount all data that you may ever want to use into the VM, so that it can be mounted selectively into containers.
> * Performance: Containers created using container require less memory than full VMs, with boot times that are comparable to containers running in a shared VM.
So: you build it as a container image and MacOS starts a VM to run it.
Edit: quite unusually for a container it runs systemd. They give an example "systemctl start postgresql".
Doing retail office deployments of custom code on employee computers is a weird niche, and you find whatever works and hope you can maintain it somehow. Cygwin was awesome though, saved me a ton of time and the client a lot of money for the moment. (The client later stipulated to all future franchisees that they had to buy only Macs, lol)