The virtualization of macOS has historically been a complex endeavor, often restricted by stringent hardware requirements and restrictive licensing. Docker-OSX represents a paradigm shift in this domain, allowing users to run macOS virtual machines within Docker containers with near-native performance. By leveraging the power of OSX-KVM and the OpenCore bootloader, this project enables the deployment of Apple's operating system on Linux and Windows hosts. This capability is particularly transformative for security researchers targeting Apple's ecosystem, developers requiring Xcode for app signing and distribution via Transporter, and DevOps engineers integrating macOS into CI/CD pipelines. The integration of X11 Forwarding allows for a graphical user interface (GUI) to be streamed from the container to the host, while the use of KVM (Kernel-based Virtual Machine) ensures that the overhead is minimized, providing a fluid experience that approximates bare-metal execution.
Architectural Core and Image Specializations
Docker-OSX is not a single entity but a suite of images tailored for specific operational requirements. The choice of image directly impacts the functionality, boot speed, and purpose of the deployment.
| Image Tag | Primary Use Case | Key Characteristics |
|---|---|---|
sickcodes/docker-osx:latest |
General Exploration & Development | Ideal for those wanting to try the system or develop/secure apps in Xcode. |
sickcodes/docker-osx:naked |
CI/CD & Automation | Stripped down for automated pipelines; supports signing into Xcode and Transporter. |
sickcodes/docker-osx:auto |
Automated Command Execution | Designed for running specific shell commands within the OS X environment. |
sickcodes/docker-osx:naked-auto |
Fast-Boot Automation | Combines the "naked" minimal footprint with the ability to execute arbitrary commands upon boot. |
sickcodes/docker-osx:big-sur |
Version-Specific Deployment | Targeted deployment of the macOS Big Sur release. |
The latest image is the primary entry point for users who need a full desktop experience. It supports the necessary hooks for signing into Apple services, which is critical for developers who must use Xcode and Transporter to push applications to the App Store. In contrast, the naked image is optimized for headless environments, such as a Jenkins or GitHub Actions runner, where a GUI is unnecessary and would only consume system resources.
Technical Deployment and Configuration
The deployment of Docker-OSX requires a precise set of flags to ensure the virtual machine can communicate with the host hardware and display the GUI.
Hardware Acceleration and KVM
The most critical requirement for near-native performance is the --device /dev/kvm flag. KVM allows the Docker container to access the Linux kernel's virtualization infrastructure. Without this, the macOS guest would rely on software emulation, resulting in catastrophic performance degradation.
GUI and X11 Forwarding
To render the macOS desktop on a Linux host, Docker-OSX utilizes X11 forwarding. This is achieved through two specific configurations:
-v /tmp/.X11-unix:/tmp/.X11-unix: This mounts the host's X11 socket into the container, allowing the guest's graphical output to be sent to the host's display server.-e "DISPLAY=${DISPLAY:-:0.0}": This environment variable tells the container which display to use, defaulting to the primary local display.
Network and Connectivity
Standard connectivity is handled via port mapping. The command -p 50922:10022 maps the guest's SSH port (10022) to the host's port 50922. This allows users to remotely manage the macOS instance via a secure shell without needing the GUI.
Advanced Configuration for Modern macOS Versions
For users deploying recent versions of macOS, such as Sonoma, Sequoia, or Tahoe, specific environment variables are required to spoof the hardware and satisfy the bootloader.
Hardware Spoofing and CPU Flags
Apple's operating systems are designed for specific hardware. To trick the installer and the kernel into booting on non-Apple hardware, Docker-OSX uses the following parameters:
CPU='Haswell-noTSX': This defines the CPU model to be emulated, ensuring compatibility with the macOS kernel's expected instruction sets.CPUID_FLAGS='kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on': These flags modify the CPUID presented to the guest. For example,vendor=GenuineIntelis essential for the OS to recognize the processor as a compatible Intel chip.
Version-Specific Deployment Commands
Depending on the target OS, the SHORTNAME and MASTER_PLIST_URL must be adjusted.
For macOS Sonoma:
bash
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e GENERATE_UNIQUE=true \
-e CPU='Haswell-noTSX' \
-e CPUID_FLAGS='kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on' \
-e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom-sonoma.plist' \
-e SHORTNAME=sonoma \
sickcodes/docker-osx:latest
For macOS Sequoia:
bash
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e GENERATE_UNIQUE=true \
-e CPU='Haswell-noTSX' \
-e CPUID_FLAGS='kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on' \
-e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom-sonoma.plist' \
-e SHORTNAME=sequoia \
sickcodes/docker-osx:latest
For macOS Tahoe:
bash
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e GENERATE_UNIQUE=true \
-e CPU='Haswell-noTSX' \
-e CPUID_FLAGS='kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on' \
-e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom-sonoma.plist' \
-e SHORTNAME=tahoe \
sickcodes/docker-osx:latest
For High Sierra (Legacy):
bash
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e SHORTNAME=high-sierra
Host-Guest Integration and Optimization
Integrating the host system with the macOS guest is essential for data transfer and network efficiency.
Shared Folder Implementation
Sharing folders between the host and the macOS guest is achieved using the 9p filesystem protocol. The process involves mapping a host directory to the Arch Linux container, which then passes it to the QEMU instance.
To implement a shared folder, the following flags are added to the docker run command:
-v "${SHARE}:/mnt/hostshare": Maps the host folder to the container's mount point.-e EXTRA="-virtfs local,path=/mnt/hostshare,mount_tag=hostshare,security_model=passthrough,id=hostshare": Passes the virtfs configuration to the underlying QEMU process.
Once the container is running, the user must execute the following command from within the macOS guest to mount the folder:
bash
sudo -S mount_9p hostshare
Network Optimization for Datacenter Deployments
When running Docker-OSX in a datacenter or cloud environment, IP forwarding must be enabled on the host to ensure the guest has proper network routing.
To enable IP forwarding for the current session:
bash
sudo sysctl -w net.ipv4.ip_forward=1
Alternatively, via the proc filesystem:
bash
sudo tee /proc/sys/net/ipv4/ip_forward <<< 1
To make this change permanent across reboots, the configuration must be written to /etc/sysctl.conf:
bash
sudo touch /etc/sysctl.conf
sudo tee -a /etc/sysctl.conf <<EOF
net.ipv4.ip_forward = 1
EOF
After modifying this file, a system reboot is required to apply the changes.
Automation and Headless Operations
For security researchers and CI/CD engineers, the ability to run macOS without a GUI is paramount.
Headless Mode Configuration
To convert a standard deployment into a headless instance, the X11 forwarding lines must be removed from the docker run command. Specifically, the following lines are deleted:
- -v /tmp/.X11-unix:/tmp/.X11-unix \
- -e "DISPLAY=${DISPLAY:-:0.0}" \
A typical headless run using a custom image looks as follows:
bash
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v "${PWD}/mac_hdd_ng.img:/image" \
sickcodes/docker-osx:naked
Executing Arbitrary Commands
The auto and naked-auto images allow users to pass specific commands to be executed inside the macOS shell upon boot. This is achieved using the OSX_COMMANDS environment variable.
Example for the auto image:
bash
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e "OSX_COMMANDS=/bin/bash -c \"put your commands here\"" \
sickcodes/docker-osx:auto
Example for the naked-auto image, which includes user authentication:
bash
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e USERNAME=yourusername \
-e PASSWORD=yourpassword \
-e "OSX_COMMANDS=/bin/bash -c \"put your commands here\"" \
sickcodes/docker-osx:naked-auto
Security Research and Ecosystem Integration
Docker-OSX is specifically engineered to facilitate high-level security research. Its ability to run macOS in an isolated environment makes it an ideal sandbox for finding vulnerabilities that could lead to bug bounties in the Apple Bug Bounty Program.
Complementary Tools and Proximity Projects
The sickcodes ecosystem extends beyond macOS virtualization to include other mobile and desktop environments:
- Dock Droid: Used for running Android in a Docker container.
- Docker-eyeOS: Specifically for running iOS 12 in a Docker container.
- Bluebubbles.app: A tool for running an iMessage relayer in Docker.
Legal and Technical Foundations
The project relies heavily on the OpenCore team's bootloader (OpenCorePkg), which provides the essential functionality for booting macOS on non-native hardware. While the project allows for the creation of proprietary software, it does not maintain affiliation with Apple Inc. All trademarks and product names remain the property of their respective holders.
Comprehensive System Specifications
The deployment of Docker-OSX is subject to specific software requirements to ensure stability and compatibility.
| Requirement | Specification |
|---|---|
| Docker Desktop Version | 4.37.1 or later |
| Hardware Acceleration | KVM (Kernel-based Virtual Machine) |
| Bootloader | OpenCore |
| Host OS | Linux (Windows via WSL2/Docker Desktop) |
| Image Size | Approximately 1.2 GB |
| Port Mapping | 50922 (Host) to 10022 (Guest) |
Conclusion
Docker-OSX is a sophisticated orchestration of KVM, QEMU, and OpenCore, encapsulated within a Docker container to provide a portable, scalable, and high-performance macOS environment. By abstracting the complexities of "Hackintosh" setups into a series of environment variables and volume mounts, it democratizes access to macOS for development and security auditing. The distinction between latest, naked, and auto images allows users to choose between a full developer workstation, a lean CI/CD node, or an automated testing agent. The integration of 9p for file sharing and the ability to spoof CPU flags like Haswell-noTSX ensures that the guest OS remains stable and performant. Ultimately, the project transforms the traditionally rigid Apple ecosystem into a flexible resource that can be deployed across heterogeneous infrastructure, provided the host meets the KVM and Docker Desktop 4.37.1+ requirements.