# Docker-OSX ## [Follow @sickcodes on Twitter](https://twitter.com/sickcodes) ![Running mac osx in a docker container](/running-mac-inside-docker-qemu.png?raw=true "OSX KVM DOCKER") Run Mac in a Docker container! Run near native OSX-KVM in Docker! X11 Forwarding! iMessage security research! Author: Sick.Codes https://sick.codes/ & https://twitter.com/sickcodes Documentation: everything is on this page! ### PR & Contributor Credits https://github.com/sickcodes/Docker-OSX/blob/master/CREDITS.md Docker Hub: https://hub.docker.com/r/sickcodes/docker-osx - sickcodes/docker-osx:latest - base recovery image (10) - sickcodes/docker-osx:big-sur - base recovery image (11) - sickcodes/docker-osx:naked - supply your own .img file - sickcodes/docker-osx:auto - 17.5GB image boot to OSX shell ## Professional Support Available! Small questions & issues: open an issue! For big projects, DM on Twitter [@sickcodes on Twitter](https://twitter.com/sickcodes) or write to us at https://sick.codes/contact. - Enterprise support, Business support, or casual support. - Custom images, custom scripts, consulting (per hour available!) - One-on-one with you, or your development team. ## Kubernetes Support Kubernetes Helm Chart & Documentation [available at ./helm](https://github.com/sickcodes/Docker-OSX/tree/master/helm) Thank you to @cephasara for this major contribution. [![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/docker-osx)](https://artifacthub.io/packages/search?repo=docker-osx) #### Follow [@sickcodes on Twitter](https://twitter.com/sickcodes) for updates or feature requests! # How to use ### There are 3 images: **latest**, **auto** and **naked**. `sickcodes/docker-osx:latest` - [I want to try it out.](https://github.com/sickcodes/Docker-OSX#quick-start-large-pre-made-image) `sickcodes/docker-osx:latest` - [I want to use Docker-OSX to develop/secure Apps in Xcode (sign into Xcode, Transporter)](https://github.com/sickcodes/Docker-OSX#basic-quick-start-docker-osx) `sickcodes/docker-osx:naked` - [I want to use Docker-OSX in CI/CD (sign into Xcode, Transporter)](https://github.com/sickcodes/Docker-OSX#fully-headless-using-my-own-image-for-cicd) Create your personal image using `:latest`. And then pull your image out. And then use duplicate that image again & again for use in `:naked`. `sickcodes/docker-osx:auto` - [I want to boot into command line only. (compile software, homebrew headless).](https://github.com/sickcodes/Docker-OSX#pre-built-image-arbitrary-command-line-arguments) `sickcodes/docker-osx:naked` - [I need iMessage/iCloud for security research.](https://github.com/sickcodes/Docker-OSX#serial-numbers) #### I need a screen. **KEEP** these two lines are in your command. Works in ANY of the machines: ```dockerfile -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ ``` #### I need headless. **REMOVE** these two lines from ANY of the machines: ```dockerfile -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ ``` #### I have used it already, and want to copy this image. Use `docker commit`, copy the ID, and then `docker start ID` **OR** [Pull out the .img file](https://github.com/sickcodes/Docker-OSX#backup-the-disk-wheres-my-disk), and then use that [.img file with :naked](https://github.com/sickcodes/Docker-OSX#quick-start-own-image-naked-container-image) # Basic Quick Start Docker-OSX ```bash docker pull sickcodes/docker-osx:latest # catalina docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ sickcodes/docker-osx:latest # big sur docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ sickcodes/docker-osx:big-sur # Wait 2-3 minutes until you see the logo. ``` # Quick Start Large Pre-Made Image Current large image size: 17.5GB This starts a container with an existing installation. This special auto image was made by @sickcodes: - SSH enabled - username is `user` - password is `alpine` - auto-updates off You will need around *50GB* of space to run this image: half for the base image + half for your runtime image. If you run out of space, you can delete all your old Docker images/history/cache by simply deleting `/var/lib/docker`, and restarting `dockerd`. ```bash docker pull sickcodes/docker-osx:auto # boot directly into a real OSX shell with no display (Xvfb) [HEADLESS] docker run -it \ --device /dev/kvm \ -p 50922:10022 \ sickcodes/docker-osx:auto # Wait 2-3 minutes until you drop into the shell. ``` ```bash docker pull sickcodes/docker-osx:auto # boot directly into a real OSX shell with a visual display [NOT HEADLESS] docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ sickcodes/docker-osx:auto ``` ### Pre-built Image + Arbitrary Command Line Arguments. ```bash docker pull sickcodes/docker-osx:auto # boot to OSX shell + display + specify commands to run inside OSX! 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 \"pwd && uname -a\"" \ sickcodes/docker-osx:auto # Boots in a minute or two! ``` ### Restart an auto container Containers that use `sickcodes/docker-osx:auto` can be stopped at started. ```bash # find last container docker ps -a # docker start old container with -i for interactive docker start -i containerid ``` # Quick Start Own Image (naked container image) This is my favourite container. You can supply an existing disk image as a docker command line argument. Supply your own local image with `-v "${PWD}/mac_hdd_ng.img:/image"` and use `sickcodes/docker-osx:naked` - Naked image is for booting any existing .img file. - By default, this image has a variable called `NOPICKER` which is `"true"`. This skips the disk selection menu. Use `-e NOPICKER=false` or any other string than the word `true` to enter the boot menu. This lets you use other disks instead of skipping the boot menu, e.g. recovery disk or disk utility. ```bash docker pull sickcodes/docker-osx:naked # run your own image + SSH # change mac_hdd_ng.img docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v "${PWD}/mac_hdd_ng.img:/image" \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ sickcodes/docker-osx:naked # run local copy of the auto image + SSH + Boot menu docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v "${PWD}/mac_hdd_ng_auto.img:/image" \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ -e "NOPICKER=false" \ sickcodes/docker-osx:naked ``` ### Fully Headless, using my own image, for CI/CD ```bash # run your own image headless + SSH docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v "${PWD}/mac_hdd_ng.img:/image" \ sickcodes/docker-osx:naked ``` # Features In Docker-OSX v4 - `sickcodes/docker-osx:big-sur` - original base recovery image for latest OS (safe) - Serial number generators. [See below or ./custom](https://github.com/sickcodes/Docker-OSX/tree/master/custom) - Full auto mode: boot straight to OSX shell and even run commands as runtime arguments! - `sickcodes/docker-osx:latest` - original base recovery image (safe) - `sickcodes/docker-osx:naked` - supply your own .img file (safe) - `sickcodes/docker-osx:auto` - Large docker image that boots to OSX shell (must trust @sickcodes) - Supply your own image using `-v "${PWD}/disk.img:/image"` - Kubernetes Helm Chart. [See ./helm](https://github.com/sickcodes/Docker-OSX/tree/master/helm) - [OSX-KVM](https://github.com/kholia/OSX-KVM) inside a Docker container! - X11 Forwarding - SSH on `localhost:50922` - QEMU + KVM! - VNC version on `localhost:8888` [vnc version is inside a separate directory, there are security risks involved with using VNC, see insid the Dockerfile](https://github.com/sickcodes/Docker-OSX/blob/master/vnc-version/Dockerfile) - Create an ARMY of the same exact container using `docker commit` - Xfvb headless mode ### All Pull Requests Welcome! Docker-OSX is a GPLv3+ Dockerfile and we need contributors just like you :) Upstream: https://github.com/kholia/OSX-KVM && the great guy [@kholia](https://twitter.com/kholia) Upstream Credits (OSX-KVM project) among many others: https://github.com/kholia/OSX-KVM/blob/master/CREDITS.md # Download The Image for sickcodes/docker-osx:naked This is the current automated image. Username is `user`, passsword is `alpine`, SSH is on, and auto-updates are off. If the download is slow, just get the image from `docker pull sickcodes/docker-osx:auto` and find it in `/var/lib/docker`. ```bash wget https://images2.sick.codes/mac_hdd_ng_auto.img docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v "${PWD}/mac_hdd_ng_auto.img:/image" \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ sickcodes/docker-osx:naked ``` ### Other cool Docker-QEMU based projects: [Run iOS in a Docker with Docker-eyeOS](https://github.com/sickcodes/Docker-eyeOS) - [https://github.com/sickcodes/Docker-eyeOS](https://github.com/sickcodes/Docker-eyeOS) # Run Docker-OSX (Original Version) ```bash docker pull sickcodes/docker-osx:latest docker run -it \ --device /dev/kvm \ --device /dev/snd \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ sickcodes/docker-osx:latest # press ctrl G if your mouse gets stuck # scroll down to troubleshooting if you have problems # need more RAM and SSH on localhost -p 50922? ``` # Run but allow SSH into OSX (Original Version)! ```bash docker run -it \ --device /dev/kvm \ --device /dev/snd \ -e RAM=4 \ -p 50922:10022 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ sickcodes/docker-osx:latest # turn on SSH after you've installed OSX in the "Sharing" settings. ssh fullname@localhost -p 50922 ``` # Autoboot into OSX after you've installed everything You can use `-e NOPICKER=true`. Old machines: ```bash # find you containerID docker ps # move the no picker script on top of the Launch script # NEW CONTAINERS docker exec containerID mv ./Launch-nopicker.sh ./Launch.sh # VNC-VERSION-CONTAINER docker exec containerID mv ./Launch-nopicker.sh ./Launch_custom.sh # LEGACY CONTAINERS docker exec containerID bash -c "grep -v InstallMedia ./Launch.sh > ./Launch-nopicker.sh chmod +x ./Launch-nopicker.sh sed -i -e s/OpenCore\.qcow2/OpenCore\-nopicker\.qcow2/ ./Launch-nopicker.sh " ``` # Requirements: KVM on the host Need to turn on hardware virtualization in your BIOS, very easy to do. Then have QEMU on the host if you haven't already ```bash # ARCH sudo pacman -S qemu libvirt dnsmasq virt-manager bridge-utils flex bison iptables-nft edk2-ovmf # UBUNTU DEBIAN sudo apt install qemu qemu-kvm libvirt-clients libvirt-daemon-system bridge-utils virt-manager # CENTOS RHEL FEDORA sudo yum install libvirt qemu-kvm # then run sudo systemctl enable libvirtd.service sudo systemctl enable virtlogd.service echo 1 | sudo tee /sys/module/kvm/parameters/ignore_msrs sudo modprobe kvm # reboot ``` # Start the same container later (persistent disk) 1. You can now pull the `.img` file out of the container, which is stored in `/var/lib/docker`, and supply it as a runtime argument to the `:naked` Docker image. See above. 2. This is for when you want to run the SAME container again later. If you don't run this you will have a new image every time. ```bash # look at your recent containers and copy the CONTAINER ID docker ps --all # docker start the container ID docker start abc123xyz567 # if you have many containers, you can try automate it with filters like this # docker ps --all --filter "ancestor=sickcodes/docker-osx" # for locally tagged/built containers # docker ps --all --filter "ancestor=docker-osx" ``` # Additional Boot Instructions - Boot the macOS Base System - Click `Disk Utility` - Erase the BIGGEST disk (around 200gb default), DO NOT MODIFY THE SMALLER DISKS. -- if you can't click `erase`, you may need to reduce the disk size by 1kb - (optional) Create a partition using the unused space to house the OS and your files if you want to limit the capacity. (For Xcode 12 partition at least 60gb.) - Click `Reinstall macOS` ## Creating images: ```bash # You can create an image of an already configured and setup container. # This allows you to effectively duplicate a system. # To do this, run the following commands # make note of your container id docker ps --all docker commit containerid newImageName # To run this image do the following docker run \ --device /dev/kvm \ --device /dev/snd \ -v /tmp/.X11-unix:/tmp/.X11-unix \ newImageName ``` # Troubleshooting libgtk permissions denied error, thanks @raoulh + @arsham ```bash echo $DISPLAY # ARCH sudo pacman -S xorg-xhost # UBUNTU DEBIAN sudo apt install x11-xserver-utils # CENTOS RHEL FEDORA sudo yum install xorg-x11-server-utils # then run xhost + ``` PulseAudio for sound (note neither [AppleALC](https://github.com/acidanthera/AppleALC) and varying [`alcid`](https://dortania.github.io/OpenCore-Post-Install/universal/audio.html) or [VoodooHDA-OC](https://github.com/chris1111/VoodooHDA-OC) have [codec support](https://osy.gitbook.io/hac-mini-guide/details/hda-fix#hda-codec) though [IORegistryExplorer](https://github.com/vulgo/IORegistryExplorer) does show the controller component working): ```bash docker run \ --device /dev/kvm \ -e AUDIO_DRIVER=pa,server=unix:/tmp/pulseaudio.socket \ -v "/run/user/$(id -u)/pulse/native:/tmp/pulseaudio.socket" \ -v /tmp/.X11-unix:/tmp/.X11-unix \ sickcodes/docker-osx ``` PulseAudio debugging: ```bash docker run \ --device /dev/kvm \ -e AUDIO_DRIVER=pa,server=unix:/tmp/pulseaudio.socket \ -v "/run/user/$(id -u)/pulse/native:/tmp/pulseaudio.socket" \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e PULSE_SERVER=unix:/tmp/pulseaudio.socket \ sickcodes/docker-osx pactl list ``` Alternative run, thanks @roryrjb ```bash docker run \ --privileged \ --net host \ --cap-add=ALL \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -v /dev:/dev \ -v /lib/modules:/lib/modules \ sickcodes/docker-osx ``` Check if your hardware virt is on ```bash egrep -c '(svm|vmx)' /proc/cpuinfo ``` Try adding yourself to the docker group ```bash sudo usermod -aG docker "${USER}" ``` Turn on docker daemon ```bash # run ad hoc sudo dockerd # or daemonize it sudo nohup dockerd & # or enable it in systemd sudo systemctl enable docker ``` # How to Enable Network Forwarding Allow ipv4 forwarding for bridged networking connections: This is not required for LOCAL installations and may cause containers behind [VPN's to leak host IP](https://sick.codes/cve-2020-15590/). If you are connecting to a REMOTE Docker-OSX, e.g. a "Mac Mini" in a datacenter, then this may boost networking: ```bash # enable for current session sudo sysctl -w net.ipv4.ip_forward=1 # OR # sudo tee /proc/sys/net/ipv4/ip_forward <<< 1 # enable permanently sudo touch /etc/sysctl.conf sudo tee -a /etc/sysctl.conf <