How to Create Linux Containers on macOS Using Apple's Container Tool
Apple's container CLI lets you run OCI-compatible Linux containers on Apple Silicon Macs as lightweight virtual machines without Docker Desktop, using native macOS virtualization and the Apple hypervisor.
Apple's open-source container repository provides a native Swift-based container runtime that brings Docker-like functionality to macOS. Unlike Docker Desktop, this tool creates tiny Linux VMs using the Apple hypervisor framework and VMnet networking, allowing you to build, run, and manage Linux containers directly on your Mac.
Architecture Overview
The container tool consists of several integrated components that work together to provide a seamless Linux container experience on macOS.
Core Components
-
containerbinary: The front-end CLI written in Swift parses sub-commands (run,build,system) via Swift Argument Parser and forwards requests to the runtime. The progress UI renders inSources/TerminalProgress/*. -
Containerization package: This low-level library referenced in
Package.swiftcreates the Linux VM via the Apple hypervisor and mounts OCI images inside it. It handles networking, storage, and Linux capabilities. -
vminitdinit process: A small init inside the VM that starts the OCI container, configures network interfaces, and forwards signals. You can replace this with a custom init image as documented inDocs/how-to.md#custom-init-image. -
VMnet network: macOS-provided virtual networking that isolates containers while assigning IP addresses in the
192.168.64.xrange.
Installation and Setup
The container tool installs as a native, signed macOS package. After installation, you must initialize the system service to create the default VMnet network.
Start the system service:
container system start
This creates the default network configuration stored in ~/.config/container/config.toml, where you can modify defaults such as CPU counts, memory limits, and network subnets.
Running Linux Containers
Once the system service is running, you can execute Linux containers using the container run command.
Run an interactive Alpine Linux shell:
container run --rm -it alpine:latest /bin/sh
The --rm flag automatically removes the container when you exit. By default, containers run with 4 CPUs and 1 GiB of memory, but you can override these limits:
container run --rm --cpus 8 --memory 32g ubuntu:latest uname -a
Networking and Storage Configuration
The tool supports Docker-compatible volume mounts and port forwarding between the host Mac and Linux containers.
Mounting Host Directories
Share files from your Mac into the container:
container run --rm \
--volume "${HOME}/Desktop/assets:/content/assets" \
python:3.11-slim ls -l /content/assets
This mounts ~/Desktop/assets to /content/assets inside the container, as implemented in the storage layer defined in Sources/ContainerPersistence/*.
Port Forwarding
Expose container ports on localhost:
container run -d --rm -p 127.0.0.1:8080:8000 \
node:latest npx http-server -a :: -p 8000
This maps the container's port 8000 to port 8080 on your Mac's loopback interface.
Custom Isolated Networks
Create separate network namespaces for container groups:
container network create foo --subnet 192.168.100.0/24
container run -d --name web --network foo nginx:alpine
container network list
Building Multi-Architecture Images
The container build command executes builds inside a dedicated builder VM, which you can configure independently in Docs/how-to.md#builder-resources.
Build images for multiple architectures simultaneously:
container build \
--arch arm64 --arch amd64 \
--tag myrepo/web:latest \
--file Dockerfile .
This produces an OCI image manifest supporting both Apple Silicon (arm64) and x86-64 (amd64) platforms without requiring QEMU emulation.
Advanced Configuration
Inspecting Container Details
Retrieve machine-readable container metadata:
container inspect web | jq .
This outputs the full JSON descriptor for the container named web, including network settings, mount points, and process status.
Using Custom Init Images
For advanced use cases, replace the default vminitd with a custom init process:
# Build your custom init binary and image
container build -t local/custom-init:latest .
# Run with custom init
container run --init-image local/custom-init:latest \
alpine:latest echo "hello from custom init"
This workflow is documented in Docs/how-to.md#custom-init-image and allows you to inject specialized initialization logic before the main container process starts.
Summary
- Apple's
containertool creates lightweight Linux VMs using the native Apple hypervisor framework, eliminating the need for Docker Desktop. - The architecture centers on the
containerCLI, Containerization Swift package, andvminitdinit process working together to run OCI-compliant containers. - Configure defaults in
~/.config/container/config.tomland manage networking via VMnet or custom isolated networks. - Build multi-architecture images using
container buildwith the--archflag for cross-platform compatibility. - All source code is available in the
apple/containerrepository, with core logic residing inSources/ContainerPersistence/*andSources/TerminalProgress/*.
Frequently Asked Questions
Do I need Docker Desktop installed to use Apple's container tool?
No. The container CLI is a standalone, native macOS application that provides its own runtime. It uses macOS's built-in virtualization frameworks (the Apple hypervisor and VMnet) rather than relying on Docker Desktop or VirtualBox.
How does container networking work on macOS?
The tool uses VMnet, macOS's native virtual network interface, to assign IP addresses (typically 192.168.64.x) to containers. By default, containers connect to the default network, but you can create isolated networks using container network create for better separation between container groups.
Can I build images for Intel Macs from my Apple Silicon Mac?
Yes. The container build command supports multi-architecture builds using the --arch flag. You can specify both --arch arm64 and --arch amd64 in a single command to produce images that run on both Apple Silicon and Intel-based Macs.
Where does the tool store container images and state?
Persistent state and OCI image data are managed by the ContainerPersistence layer (Sources/ContainerPersistence/*). Configuration files live in ~/.config/container/, while the underlying VM state and image layers are stored in the macOS library directory, similar to other container runtimes.
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 →