├── .dockerignore ├── .gitignore ├── Dockerfile ├── README.md ├── docker-compose.yml └── headless.sh /.dockerignore: -------------------------------------------------------------------------------- 1 | images 2 | *.qcow2 3 | *.img 4 | .idea 5 | firmware -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | firmware/ 2 | *.qcow2 3 | .idea/ 4 | *.img -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | RUN apk add libvirt-daemon qemu-img qemu-system-x86_64 openrc bash 3 | RUN rc-update add libvirtd 4 | COPY . /macostools/ 5 | WORKDIR /macostools 6 | ENTRYPOINT ["./headless.sh"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # macOS in Docker 2 | 3 | ##### Built on the great work from [foxlet] 4 | 5 | _Runs a macOS image on QEMU in a docker container, with VNC, SSH and SPICE access on alpine linux_ 6 | 7 | ## Setup 8 | 9 | ### Requirements: 10 | - Docker 11 | - A MacOS `.qcow2` image (You can build a new one using foxlet's [macOS-Simple-KVM tool]) 12 | - A `BaseSystem.img` file (Convert it yourself from the .dmg, or use foxlet's [macOS-Simple-KVM tool]) 13 | - The `ESP.qcow2` file from [macOS-Simple-KVM tool] 14 | - the `/firmware` folder from foxlet's [macOS-Simple-KVM tool] 15 | - KVM Capable Linux host with KVM enabled 16 | - (This probably won't run on Windows or Mac docker due to the docker shim using the kvm from the host system already) 17 | 18 | 19 | ### Quickstart 20 | - Clone the [macOS-Simple-KVM tool]: `git clone https://github.com/foxlet/macOS-Simple-KVM.git` 21 | - Clone this repo 22 | - Copy the `firmware` directory from the macOS-Simple-KVM tool and your .qcow2 image into this repository 23 | - Copy/Move your `BaseSystem.img` and `MyDisk.qcow2` image into this directory 24 | - Run `docker-compose up` 25 | 26 | VNC will be available on localhost port 5900 \ 27 | SSH will be available on localhost port 2222 (If turned on in the `Settings > Sharing > Remote Access` in your macOS image) \ 28 | SPICE (along with system audio) will be available on localhost port 5930 (`remote-viewer spice://localhost:5930`) 29 | 30 | 31 | ## Build Yourself 32 | 33 | `docker build . -t macos-docker` 34 | 35 | To run, mount the following volumes: 36 | 37 | - ./MyDisk.qcow2:/macostools/MyDisk.qcow2 38 | - ./BaseSystem.img:/macostools/BaseSystem.img 39 | - ./ESP.qcow2:/macostools/ESP.qcow2 40 | - ./firmware:/macostools/firmware 41 | 42 | And set the following environment variables: 43 | - SYSTEM_DISK=MyDisk.qcow2 44 | - HEADLESS=1 45 | - MEM=2G 46 | - CPUS=4 47 | - SPICE=1 48 | 49 | Refer to the macOS-Simple-KVM repo for more info on customization 50 | 51 | ## Notes 52 | The base image built by the `macOS-Simple-KVM` tool has UUIDs that have been flagged by apple from too many setups, and so you likely won't be able to sign in to an apple account until you change them. 53 | I recommend [clover-configurator] to modify the system to have new UUIDs before attempting to sign in to your apple account. 54 | You can also use the same tool to modify the default resolution of your macOS image 55 | 56 | 57 | [clover-configurator]: https://mackie100projects.altervista.org/download-clover-configurator/ 58 | [foxlet]: https://github.com/foxlet/macOS-Simple-KVM 59 | [macOS-Simple-KVM tool]: https://github.com/foxlet/macOS-Simple-KVM 60 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | services: 3 | macos: 4 | container_name: macos 5 | privileged: true 6 | hostname: macos 7 | image: taylorcoffelt/macos-docker 8 | environment: 9 | - SYSTEM_DISK=MyDisk.qcow2 10 | - HEADLESS=1 11 | - MEM=4G 12 | - CPUS=4 13 | - SPICE=1 14 | ports: 15 | - "5900:5900" 16 | - "5930:5930" 17 | - "2222:22" 18 | volumes: 19 | - ./MyDisk.qcow2:/macostools/MyDisk.qcow2 20 | - ./BaseSystem.img:/macostools/BaseSystem.img 21 | - ./ESP.qcow2:/macostools/ESP.qcow2 22 | - ./firmware:/macostools/firmware -------------------------------------------------------------------------------- /headless.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | OSK="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" 4 | VMDIR=$PWD 5 | OVMF=$VMDIR/firmware 6 | 7 | [[ -z "$MEM" ]] && { 8 | MEM="1G" 9 | } 10 | 11 | [[ -z "$CPUS" ]] && { 12 | CPUS=1 13 | } 14 | 15 | [[ -z "$SYSTEM_DISK" ]] && { 16 | echo "Please set the SYSTEM_DISK environment variable" 17 | exit 1 18 | } 19 | 20 | [[ -r "$SYSTEM_DISK" ]] || { 21 | echo "Can't read system disk image: $SYSTEM_DISK" 22 | exit 1 23 | } 24 | 25 | MOREARGS=() 26 | 27 | [[ "$HEADLESS" = "1" ]] && { 28 | MOREARGS+=(-nographic -vnc :0 -k en-us) 29 | } 30 | 31 | [[ "$SPICE" = "1" ]] &&{ 32 | MOREARGS+=(-spice port=5930,disable-ticketing) 33 | } 34 | 35 | qemu-system-x86_64 \ 36 | -enable-kvm \ 37 | -m $MEM \ 38 | -machine q35,accel=kvm \ 39 | -smp $CPUS \ 40 | -cpu Penryn,vendor=GenuineIntel,kvm=on,+sse3,+sse4.2,+aes,+xsave,+avx,+xsaveopt,+xsavec,+xgetbv1,+avx2,+bmi2,+smep,+bmi1,+fma,+movbe,+invtsc \ 41 | -device isa-applesmc,osk="$OSK" \ 42 | -smbios type=2 \ 43 | -drive if=pflash,format=raw,readonly,file=$OVMF/OVMF_CODE.fd \ 44 | -drive if=pflash,format=raw,file=$OVMF/OVMF_VARS-1024x768.fd \ 45 | -vga qxl \ 46 | -device ich9-intel-hda -device hda-output \ 47 | -usb -device usb-kbd -device usb-tablet \ 48 | -netdev user,id=net0,hostfwd=tcp::22-:22 \ 49 | -device e1000-82545em,netdev=net0,id=net0,mac=ba:83:a1:91:76:3c \ 50 | -device ich9-ahci,id=sata \ 51 | -drive id=ESP,if=none,format=qcow2,file=ESP.qcow2 \ 52 | -device ide-hd,bus=sata.2,drive=ESP \ 53 | -drive id=InstallMedia,format=raw,if=none,file=BaseSystem.img \ 54 | -device ide-hd,bus=sata.3,drive=InstallMedia \ 55 | -drive id=SystemDisk,if=none,file="${SYSTEM_DISK}" \ 56 | -device ide-hd,bus=sata.4,drive=SystemDisk \ 57 | ${MOREARGS[@]} --------------------------------------------------------------------------------