Running macOS in Docker

Why Docker?

Actually this (Docker-OSX) is a QEMU VM running under an Arch Docker. However the setup is streamlined and just more or less copy paste than setting up VM from scratch


  • All code blocks can be copied into a script to run
  • VNC in this setup is not secured with password in ANYWAY, so please use caution and only use local VNC or SSH tunnel to connect to VNC
  • There's a nakedvnc dockerfile in Docker-OSX repo but no prebuilt image. This has proper encrypted (?) VNC setup so if you have resource to compose/build docker image you are welcome to do that.
  • Headless option (remove to use head-attached): -e EXTRA="-display none"
  • Dangerous option: -p 5999:5999. This will forward your container VNC port to localhost port. DO NOT EXPOSE THIS PORT TO PUBLIC unless you use nakedvnc image with proper encryption (?)
  • VNC can be setup with password if you follow the Docker-OSX repo guide, but I won't talk much about it here. SSH tunnel is secure enough for the job.
  • Screen WIDTH/HEIGHT can be modified freely. 1366x768 works best for me, ymmv.

Prerequisites Setup

TigerVNC-Viewer or equivalent VNC Viewer/Client (Optional) screen for interacting with docker -ai

Initiate base image

docker run -it \
--name macos_base \
--device /dev/kvm \
-p 50922:10022 \
-p 5999:5999 \
-e NOPICKER=true \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e EXTRA="-display none -vnc" \
-e WIDTH=1366 \
-e HEIGHT=768 \
  • (Headless) connect to server VNC at port localhost:5999 (no password, NOTE: very insecure, local/ssh-tunnel only). For remote (in Local Network) use :5999 to connect
  • Install macOS:
    • Install macOS as normal, login with iCloud if needed
    • Note: DO NOT OPEN iMessage yet
  • Shutdown in QEMU cmd using quit, or shutdown from inside VNC session

Extract image

Explain: find mac_hdd_ng.img from /var/lib/docker (make sure file size make sense), copy to current folder
sudo cp `sudo find /var/lib/docker -size +10G -name mac_hdd_ng.img | head -1` .

Generate unique serial

mkdir tmp && cd tmp
curl -O
# wget
chmod +x
./ --count 1 --output-env ../
cd ..
rm -rf tmp
OR if you already have a working serial configs and just want to migrate to docker solution:
  • Create file with nano
  • Content of the file
export WIDTH="1366"
export HEIGHT="768"
  • Ctrl+X then Y, Enter to save and exit

First run

source ./
sudo docker run -i \
--name macos \
--privileged \
--device /dev/kvm \
-v "${PWD}/mac_hdd_ng.img:/image" \
-p 5999:5999 \
-p 1234:1234 \
-p 50922:10022 \
-e TERMS_OF_USE=i_agree \
-e NOPICKER=true \
-e UUID="${UUID}" \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e EXTRA="-display none -vnc" \
-e WIDTH="${WIDTH}" \

Subsequent run

screen is totally optional, I just want to have stdio attached for debugging in QEMU shell
screen -dmS macos-docker docker start -ai macos

Post-install Notes/Tips

  • SSH port is 50922, you need to enable macOS SSH from Sharing preferences first.
  • scp is useful for transferring files from Docker macOS and host
  • Read about ssh -L for SSH tunneling to make VNC session secure.