How to Run Custom Linux Distributions on Mac with the Container Tool
You can run custom Linux distributions on Mac by building an OCI image with an init system like systemd, registering it via container machine create, and launching it with container machine run, which provides a persistent Linux VM that automatically shares your macOS home directory.
The container tool (formerly Docker for Apple Silicon) from the Apple container repository enables developers to run custom Linux distributions on macOS using lightweight virtual machines backed by OCI-compatible images. Unlike traditional containers, a container machine runs a full Linux init system such as systemd inside a hypervisor-based VM, giving you a complete Linux environment while maintaining seamless integration with macOS networking and file systems. This architecture allows you to run any distribution—Alpine, Ubuntu, Fedora, or Debian—directly on Apple Silicon or Intel Macs.
Architecture of Container Machines
The container tool leverages Apple's hypervisor framework to launch sandboxed Linux VMs through the vminitd helper, with orchestration logic implemented in Swift sources such as Sources/ContainerXPC/XPCServer.swift. Each container machine boots a minimal Linux kernel bundled with the tool and mounts an OCI rootfs image as its filesystem, requiring an init binary at /sbin/init to manage the system. When you create a machine, the tool writes a configuration file to ~/.config/container/machines/<name>.toml that stores the image reference and resource settings, while automatically bind-mounting your macOS $HOME directory to /home/<username> inside the VM.
Building a Custom Linux Distribution Image
To run your preferred distribution, you must first create an OCI image containing a compatible init system. Below is a minimal Dockerfile for Ubuntu 24.04 that installs systemd and prepares the image for use as a container machine, adapted from the docs/container-machine.md documentation.
# Dockerfile – custom Ubuntu container machine
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 && \
> /var/lib/dbus/machine-id
RUN systemctl set-default multi-user.target && \
systemctl mask \
dev-hugepages.mount \
sys-fs-fuse-connections.mount \
systemd-update-utmp.service \
systemd-tmpfiles-setup.service && \
systemctl disable networkd-dispatcher.service
RUN sed -i -e 's/^AcceptEnv LANG LC_*/#AcceptEnv LANG LC_*/' /etc/ssh/sshd_config
Save this as Dockerfile in your project directory, then build the image using the container CLI. The build process runs inside a lightweight builder VM managed by the tool, with progress UI handled by Sources/TerminalProgress/.
container build -t local/ubuntu-machine:latest .
Creating and Running Container Machines
Once the image is built, register it as a persistent virtual machine using container machine create. This command records the image reference in the machine configuration file and prepares the VM for execution.
container machine create local/ubuntu-machine:latest --name ubuntu-dev
Start an interactive shell inside the Linux VM using container machine run. Your macOS username and home directory are immediately available inside the VM, allowing you to edit files on macOS using native applications and compile or run them inside Linux.
# Launch an interactive shell
container machine run -n ubuntu-dev
# Execute a single command
container machine run -n ubuntu-dev uname -a
The integration preserves your working directory context when transitioning between macOS and the Linux environment, as documented in docs/how-to.md.
Resource Configuration and Advanced Options
You can adjust CPU and memory allocation for existing machines using the container machine set command. These changes take effect after the next stop and start cycle.
container machine set -n ubuntu-dev cpus=4 memory=8G
container machine stop ubuntu-dev
container machine run -n ubuntu-dev
For specialized workloads requiring hardware virtualization support inside the VM (such as running Docker within your Linux distribution), provide a custom kernel compiled with CONFIG_KVM=y and enable nested virtualization during machine creation.
container machine create \
--virtualization \
--kernel /path/to/vmlinux-kvm \
--name kvm-dev \
local/ubuntu-machine:latest
This configuration is detailed in the "Nested virtualization and custom kernels" section of docs/container-machine.md.
Summary
- Container machines are persistent Linux VMs that run OCI images with init systems like
systemdon macOS using Apple's hypervisor framework. - Build custom distribution images with standard Dockerfiles using
container build, ensuring the image includes/sbin/initand is defined inPackage.swiftas compatible. - Register machines with
container machine create, which stores configuration in~/.config/container/machines/<name>.toml. - Launch environments with
container machine run, which automatically shares your macOS$HOMEdirectory with the Linux VM. - Configure resources and custom kernels using
container machine setand creation flags for specialized hardware requirements.
Frequently Asked Questions
What Linux distributions are supported by the container tool?
You can run any Linux distribution that supports the systemd init system or provides an alternative init binary at /sbin/init. The repository includes examples for Ubuntu, Debian, Fedora, and Alpine in examples/container-machine-vscode/. As long as you can build an OCI-compatible image containing an init system, the container tool can boot it as a container machine.
Do I need Docker Desktop installed to use container?
No. The container tool is a standalone Swift package defined in Package.swift that includes its own container engine and build system. It uses its own storage for images and machines, independent of Docker Desktop, though it uses standard OCI image formats and Dockerfile syntax compatible with Docker.
How does file sharing work between macOS and the Linux VM?
The container tool automatically bind-mounts your macOS $HOME directory into the VM at /home/<username>, allowing seamless access to files without manual syncing or copying. This integration is handled by the VM orchestration layer in Sources/ContainerXPC/ and persists across reboots of the container machine.
Can I run graphical Linux applications using container machines?
While the primary use case targets development environments and command-line tools, you can run graphical applications by forwarding X11 or using other display protocols, as the VM includes standard networking and file system access. The VS Code integration example in examples/container-machine-vscode/README.md demonstrates how to use the container machine as a full-featured remote development environment.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →