2020-06-04 19:01:38 +08:00
# Docker-OSX
2020-09-20 16:49:12 +08:00
## [Follow @sickcodes on Twitter](https://twitter.com/sickcodes)
2020-09-26 14:26:38 +08:00
### V2.6
# Features In Docker-OSX v2.6
2020-09-20 16:49:12 +08:00
- CI/CD weaponization thru vnc and xdotool
- OSX-KVM
- X11 Forwarding
- SSH on localhost:50922
- QEMU
- VNC on localhost:8888 [vnc version is inside a separate directory ](https://github.com/sickcodes/Docker-OSX/blob/master/vnc-version/Dockerfile )
- Create an ARMY using `docker commit`
- XFVB HEADLESS (use vnc)
2020-10-07 00:42:34 +08:00
### Pull Requests Welcome!
2020-06-05 02:31:47 +08:00
![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!
2020-06-15 12:33:29 +08:00
Author: Sick.Codes https://sick.codes/ & https://twitter.com/sickcodes
2020-06-05 02:38:52 +08:00
2020-10-07 00:42:34 +08:00
PR & Contributor Credits: https://github.com/sickcodes/Docker-OSX/blob/master/CREDITS.md
2020-09-20 16:49:12 +08:00
2020-10-07 00:42:34 +08:00
Upstream: https://github.com/kholia/OSX-KVM && the great guy [@kholia ](https://twitter.com/kholia )
2020-09-20 16:49:12 +08:00
2020-10-07 00:42:34 +08:00
Upstream Credits (OSX-KVM project) among many others: https://github.com/kholia/OSX-KVM/blob/master/CREDITS.md
2020-06-05 02:31:47 +08:00
2020-06-05 06:58:42 +08:00
Docker Hub: https://hub.docker.com/r/sickcodes/docker-osx
2020-10-05 16:01:45 +08:00
### 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 )
2020-10-07 00:42:34 +08:00
# Run Docker-OSX
2020-06-05 11:49:15 +08:00
2020-09-20 16:49:12 +08:00
```bash
2020-06-05 02:35:57 +08:00
2020-09-26 14:26:38 +08:00
docker pull sickcodes/docker-osx:latest
2020-06-05 02:35:57 +08:00
2020-10-07 00:42:34 +08:00
docker run \
--device /dev/kvm \
2020-10-05 16:01:45 +08:00
--device /dev/snd \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
sickcodes/docker-osx:latest
2020-06-05 02:35:57 +08:00
2020-06-05 05:10:05 +08:00
# press ctrl G if your mouse gets stuck
2020-06-05 12:11:30 +08:00
# scroll down to troubleshooting if you have problems
2020-06-05 11:49:15 +08:00
2020-10-05 16:01:45 +08:00
# need more RAM and SSH on localhost -p 50922?
2020-06-07 14:44:57 +08:00
2020-10-07 00:42:34 +08:00
```
2020-10-29 14:52:10 +08:00
# Run but allow SSH into OSX!
2020-10-07 00:42:34 +08:00
```bash
docker run \
--device /dev/kvm \
2020-10-05 16:01:45 +08:00
--device /dev/snd \
-e RAM=4 \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
2020-10-07 00:42:34 +08:00
-e "DISPLAY=${DISPLAY:-:0.0}" \
2020-10-05 16:01:45 +08:00
sickcodes/docker-osx:latest
2020-06-15 21:07:37 +08:00
2020-10-07 00:42:34 +08:00
# turn on SSH after you've installed OSX in the "Sharing" settings.
2020-06-15 21:07:37 +08:00
ssh fullname@localhost -p 50922
2020-06-07 14:44:57 +08:00
2020-06-05 05:10:05 +08:00
```
2020-10-07 01:12:45 +08:00
# Autoboot into OSX after you've installed everything
```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
2020-11-06 20:42:00 +08:00
# VNC-VERSION-CONTAINER
docker exec containerID mv ./Launch-nopicker.sh ./Launch_custom.sh
2020-10-07 01:12:45 +08:00
# 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
"
```
2020-06-05 09:57:01 +08:00
# Requirements: KVM on the host
2020-06-05 08:27:49 +08:00
Need to turn on hardware virtualization in your BIOS, very easy to do.
2020-10-07 00:42:34 +08:00
Then have QEMU on the host if you haven't already
2020-09-20 16:49:12 +08:00
```bash
2020-06-05 08:27:49 +08:00
# ARCH
2020-09-20 16:49:12 +08:00
sudo pacman -S qemu libvirt dnsmasq virt-manager bridge-utils flex bison iptables-nft edk2-ovmf
2020-06-05 08:27:49 +08:00
# UBUNTU DEBIAN
sudo apt install qemu qemu-kvm libvirt-clients libvirt-daemon-system bridge-utils virt-manager
# CENTOS RHEL FEDORA
2020-10-07 00:42:34 +08:00
sudo yum install libvirt qemu-kvm
2020-06-05 08:27:49 +08:00
# then run
sudo systemctl enable libvirtd.service
sudo systemctl enable virtlogd.service
2020-10-05 16:01:45 +08:00
2020-06-05 08:27:49 +08:00
sudo modprobe kvm
2020-10-05 16:01:45 +08:00
# reboot
```
2020-10-04 07:36:12 +08:00
2020-06-05 05:10:05 +08:00
# Start the same container later (persistent disk)
2020-06-05 12:11:30 +08:00
2020-10-07 00:42:34 +08:00
This is for when you want to run the SAME container again later.
2020-06-05 12:11:30 +08:00
If you don't run this you will have a new image every time.
2020-09-20 16:49:12 +08:00
```bash
2020-06-06 10:25:06 +08:00
# look at your recent containers and copy the CONTAINER ID
docker ps --all
2020-06-05 05:10:05 +08:00
2020-06-06 10:25:06 +08:00
# docker start the container ID
docker start abc123xyz567
2020-06-05 11:49:15 +08:00
2020-06-06 10:25:06 +08:00
# if you have many containers, you can try automate it with filters like this
# docker ps --all --filter "ancestor=sickcodes/docker-osx"
2020-10-05 16:01:45 +08:00
# for locally tagged/built containers
# docker ps --all --filter "ancestor=docker-osx"
2020-06-05 11:49:15 +08:00
2020-06-05 02:31:47 +08:00
```
2020-06-05 04:25:29 +08:00
# Additional Boot Instructions
2020-09-20 16:49:12 +08:00
- Boot the macOS Base System
2020-06-05 04:25:29 +08:00
2020-10-07 00:42:34 +08:00
- Click `Disk Utility`
2020-06-05 04:25:29 +08:00
2020-09-20 16:49:12 +08:00
- Erase the BIGGEST disk (around 200gb default), DO NOT MODIFY THE SMALLER DISKS.
2020-10-07 00:42:34 +08:00
-- if you can't click `erase` , you may need to reduce the disk size by 1kb
2020-06-05 04:25:29 +08:00
2020-10-15 01:11:34 +08:00
- (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.)
2020-10-07 00:42:34 +08:00
- Click `Reinstall macOS`
2020-06-05 04:25:29 +08:00
2020-08-24 04:22:45 +08:00
## Creating images:
2020-09-20 16:49:12 +08:00
```bash
2020-10-07 00:42:34 +08:00
# You can create an image of an already configured and setup container.
# This allows you to effectively duplicate a system.
2020-08-24 04:22:45 +08:00
# To do this, run the following commands
2020-10-07 00:42:34 +08:00
# make note of your container id
docker ps --all
docker commit containerid newImageName
2020-08-24 04:22:45 +08:00
# To run this image do the following
2020-10-07 00:42:34 +08:00
docker run \
--device /dev/kvm \
--device /dev/snd \
-v /tmp/.X11-unix:/tmp/.X11-unix \
newImageName
2020-08-24 04:22:45 +08:00
```
2020-06-05 09:39:15 +08:00
# Troubleshooting
2020-06-06 02:41:37 +08:00
libgtk permissions denied error, thanks @raoulh + @arsham
2020-09-20 16:49:12 +08:00
```bash
2020-06-06 02:41:37 +08:00
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
2020-06-05 20:53:19 +08:00
# then run
xhost +
2020-06-05 11:49:15 +08:00
```
2020-09-20 17:47:23 +08:00
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):
2020-10-07 00:42:34 +08:00
2020-09-20 17:47:23 +08:00
```bash
2020-10-07 00:42:34 +08:00
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
2020-09-20 17:47:23 +08:00
```
2020-10-07 00:42:34 +08:00
2020-09-20 17:47:23 +08:00
PulseAudio debugging:
```bash
2020-10-07 00:42:34 +08:00
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
2020-09-20 17:47:23 +08:00
```
2020-06-05 12:11:30 +08:00
Alternative run, thanks @roryrjb
2020-06-15 12:33:29 +08:00
2020-09-20 16:49:12 +08:00
```bash
2020-10-07 00:42:34 +08:00
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
2020-09-20 16:49:12 +08:00
```
2020-06-05 12:11:30 +08:00
2020-06-05 09:39:15 +08:00
Check if your hardware virt is on
2020-06-15 12:33:29 +08:00
2020-09-20 16:49:12 +08:00
```bash
egrep -c '(svm|vmx)' /proc/cpuinfo
```
2020-06-05 09:39:15 +08:00
Try adding yourself to the docker group
2020-06-15 12:33:29 +08:00
2020-09-20 16:49:12 +08:00
```bash
sudo usermod -aG docker "${USER}"
```
2020-06-05 09:39:15 +08:00
Turn on docker daemon
2020-06-15 12:33:29 +08:00
2020-09-20 16:49:12 +08:00
```bash
2020-10-07 00:42:34 +08:00
# run ad hoc
2020-09-20 16:49:12 +08:00
sudo dockerd
2020-10-07 00:42:34 +08:00
2020-09-20 16:49:12 +08:00
# or daemonize it
sudo nohup dockerd &
2020-10-07 00:42:34 +08:00
# or enable it in systemd
sudo systemctl enable docker
2020-09-20 16:49:12 +08:00
```
2020-06-05 05:42:21 +08:00
2020-10-07 00:42:34 +08:00
# 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:
2020-06-05 05:42:21 +08:00
2020-09-20 16:49:12 +08:00
```bash
2020-10-07 00:42:34 +08:00
# enable for current session
sudo sysctl -w net.ipv4.ip_forward=1
2020-06-05 05:42:21 +08:00
2020-10-07 00:42:34 +08:00
# OR
# sudo tee /proc/sys/net/ipv4/ip_forward <<< 1
# enable permanently
sudo touch /etc/sysctl.conf
sudo tee -a /etc/sysctl.conf < < EOF
net.ipv4.ip_forward = 1
EOF
# OR edit manually
nano /etc/sysctl.conf || vi /etc/sysctl.conf || vim /etc/sysctl.conf
# now reboot
```
2020-12-17 00:57:57 +08:00
# How to reduce the size of the image
* Start up the container as usual, and remove unnecessary files. A useful way
to do this is to use `du -sh *` starting from the `/` directory, and find
large directories where files can be removed. E.g. unnecessary cached files,
Xcode platforms, etc.
* Once you are satisfied with the amount of free space, enable trim with `sudo trimforce enable` , and reboot.
* Zero out the empty space on the disk with `dd if=/dev/zero of=./empty && rm -f empty`
* Shut down the VM and copy out the qcow image with `docker cp stoppedcontainer:/home/arch/OSX-KVM/mac_hdd_ng.img .`
* Run `qemu-img check -r all mac_hdd_ng.img` to fix any errors.
* Run `qemu-img convert -O qcow2 mac_hdd_ng.img deduped.img` and check for errors again
* OPTIONAL: Run `qemu-img -c -O qcow2 deduped.img compressed.img` to further compress the image. This may reduce the runtime speed though, but it should reduce the size by roughly 25%.
* Check for errors again, and build a fresh docker image. E.g. with this Dockerfile
```
FROM sickcodes/docker-osx
USER arch
COPY --chown=arch ./deduped.img /home/arch/OSX-KVM/mac_hdd_ng.img
```
# How to run in headless mode
First make sure [autoboot is enabled ](#autoboot-into-osx-after-youve-installed-everything )
Next, you will want to set up SSH to be automatically started.
```bash
sudo systemsetup -setremotelogin on
```
Then run it with these arguments.
```bash
# Run with the -nographic flag, and enable a telnet interface
docker run \
--device /dev/kvm \
-p 50922:10022 \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e EXTRA="-monitor telnet::45454,server,nowait -nographic -serial null"
```
Optionally, you can enable the SPICE protocol, which allows you to use
`remote-viewer` to access it rather than VNC.
```bash
docker run \
--device /dev/kvm \
-p 50922:10022 \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e EXTRA="-monitor telnet::45454,server,nowait -nographic -serial null -spice disable-ticketing,port=3001"
```
Then simply do `remote-viewer spice://localhost:3001` and add `--spice-debug` for debugging.
2020-10-07 00:42:34 +08:00
# How to install Docker if you don't have Docker already
```bash
### Arch
sudo pacman -S docker
2020-06-05 05:42:21 +08:00
sudo groupadd docker
2020-09-20 16:49:12 +08:00
sudo usermod -aG docker "${USER}"
2020-06-05 05:42:21 +08:00
### Ubuntu
2020-10-07 00:42:34 +08:00
sudo apt remove docker docker-engine docker.io containerd runc -y
sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common -y
2020-09-20 16:49:12 +08:00
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
2020-06-05 05:42:21 +08:00
apt-key fingerprint 0EBFCD88
2020-10-07 00:42:34 +08:00
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update -y
sudo apt install docker-ce docker-ce-cli containerd.io -y
2020-06-05 09:39:15 +08:00
sudo groupadd docker
2020-09-20 16:49:12 +08:00
sudo usermod -aG docker "${USER}"
2020-06-05 05:42:21 +08:00
```
2020-10-07 00:42:34 +08:00
### Fedora: if you have no internet connectivity from the VM, and you are using bridge networking:
2020-07-07 18:09:20 +08:00
2020-09-20 16:49:12 +08:00
```bash
2020-07-07 18:09:20 +08:00
# Set the docker0 bridge to the trusted zone
sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0
sudo firewall-cmd --reload
```
2020-09-20 16:49:12 +08:00
# Backup the disk (Where's my disk?)
2020-06-05 05:23:16 +08:00
2020-09-20 16:49:12 +08:00
You can use `docker cp`
2020-06-05 05:23:16 +08:00
2020-09-20 16:49:12 +08:00
```bash
# docker copy your image OUT of your container (warning, double disk space)
docker cp oldcontainerid:/home/arch/OSX-KVM/mac_hdd_ng.img .
2020-06-05 05:23:16 +08:00
```
2020-09-20 16:49:12 +08:00
Or if you lost your container, find it with this:
```bash
2020-11-28 22:12:44 +08:00
# fast way, find 10 gigabyte OSX disks hiding in your docker container storage
2020-06-15 21:07:37 +08:00
sudo find /var/lib/docker -size +10G | grep mac_hdd_ng.img
2020-11-28 22:12:44 +08:00
# you can move (mv) it somewhere, using cp can take loads of disk space
2020-09-20 16:49:12 +08:00
sudo mv somedir/mac_hdd_ng.img .
2020-06-05 05:23:16 +08:00
2020-11-28 22:12:44 +08:00
```
# Use an Old Docker-OSX Disk in a Fresh Container (Replication)
You do not have to reinstall everything, you can simply:
- start a new container
- overwrite the .img in the new container with your big old one
```bash
# start a new docker-osx container
# you can start with ssh, without, or vnc, because they are all interchangable.
# get the NEW container id
2020-09-20 16:49:12 +08:00
docker ps
2020-06-05 05:23:16 +08:00
2020-11-28 22:12:44 +08:00
# docker cp your OLD disk into the NEW container
2020-09-20 16:49:12 +08:00
docker cp ./mac_hdd_ng.img newcontainerid:/home/arch/OSX-KVM/mac_hdd_ng.img
2020-06-05 05:23:16 +08:00
2020-11-28 22:12:44 +08:00
# kill the NEW container
docker kill newcontainerid
# start the NEW container and it just works
docker start newcontainerid
2020-06-05 05:23:16 +08:00
```
2020-11-28 22:12:44 +08:00
# DESTROY: Wipe old images to get
2020-06-05 05:23:16 +08:00
2020-10-07 00:42:34 +08:00
This is useful for getting disk space back.
2020-11-28 22:12:44 +08:00
It will delete ALL your old (and new) docker containers.
2020-10-07 00:42:34 +08:00
2020-09-20 16:49:12 +08:00
```bash
2020-06-05 05:10:05 +08:00
# WARNING deletes all old images, but saves disk space if you make too many containers
2020-09-20 16:49:12 +08:00
# The following command will make your containers RIP
2020-06-05 05:10:05 +08:00
docker system prune --all
docker image prune --all
```
2020-09-20 16:49:12 +08:00
# INSTANT OSX-KVM in a BOX!
2020-06-05 02:31:47 +08:00
This Dockerfile automates the installation of OSX-KVM inside a docker container.
2020-06-15 12:33:29 +08:00
It will build a Catalina Disk with up to 200GB of space.
2020-06-05 02:31:47 +08:00
You can change the size and version using build arguments (see below).
This file builds on top of the work done by Dhiru Kholia and many others on the OSX-KVM project.
# Custom Build
2020-09-20 16:49:12 +08:00
```bash
2020-06-05 02:31:47 +08:00
docker build -t docker-osx:latest \
2020-11-28 22:12:44 +08:00
--build-arg VERSION=10.14.6 \
--build-arg SIZE=200G
2020-09-20 16:49:12 +08:00
```
2020-06-05 02:31:47 +08:00
2020-11-28 22:12:44 +08:00
# Custom QEMU Arguments (passthrough devices)
Pass any devices/directories to the Docker container & the QEMU arguments using the handy `-e EXTRA=` runtime options.
2020-09-20 16:49:12 +08:00
```bash
2020-06-15 12:33:29 +08:00
docker run \
2020-11-28 22:12:44 +08:00
-e RAM=4 \
-e SMP=4 \
-e CORES=4 \
-e EXTRA='-usb -device usb-host,hostbus=1,hostaddr=8' \
-e INTERNAL_SSH_PORT=23 \
--device /dev/kvm \
--device /dev/snd \
-v /tmp/.X11-unix:/tmp/.X11-unix \
docker-osx:latest
2020-06-15 12:33:29 +08:00
2020-06-05 02:31:47 +08:00
```
2020-10-05 16:01:45 +08:00
## What is `${DISPLAY:-:0.0}`?
`$DISPLAY` is the shell variable that refers to your X11 display server.
`${DISPLAY}` is the same, but allows you to join variables like this:
- e.g. `${DISPLAY}_${DISPLAY}` would print `:0.0_:0.0`
- e.g. `$DISPLAY_$DISPLAY` would print `:0.0`
...because `$DISPLAY_` is not `$DISPLAY`
`${variable:-fallback}` allows you to set a "fallback" variable to be substituted if `$variable` is not set.
You can also use `${variable:=fallback}` to set that variable (in your current terminal).
In Docker-OSX, we assume, `:0.0` is your default `$DISPLAY` variable.
You can see what yours is
```bash
echo $DISPLAY
```
Hence, `${DISPLAY:-:0.0}` will use whatever variable your X11 server has set for you, else `:0.0`
2020-11-28 22:12:44 +08:00
## What is `-v /tmp/.X11-unix:/tmp/.X11-unix`?
`-v` is a Docker command-line option that lets you pass a volume to the container.
The directory that we are letting the Docker container use is a X server display socket.
`/tmp/.X11-unix`
If we let the Docker container use the same display socket as our own environment, then any applications you run inside the Docker container will show up on your screen too! [https://www.x.org/archive/X11R6.8.0/doc/RELNOTES5.html ](https://www.x.org/archive/X11R6.8.0/doc/RELNOTES5.html )
2020-10-05 16:01:45 +08:00
2020-06-05 02:31:47 +08:00
## Todo:
```
2020-11-28 22:12:44 +08:00
- Security Documentation
- GPU Acceleration: Coming Soon
2020-09-20 16:49:12 +08:00
- Virt-manager
2020-06-05 20:53:19 +08:00
```