Wednesday, June 3, 2026

Run macOS in linux docker container

To be able to run macOS in linux docker container to access macOS applications without switch back and forth makes life easy. This project allow you to do that. The instruction given is very tricky, so I have written a step by step how to begin.


0. This is the main project which we will work on. Essentially we need to build an image where the image is not found in dockerhub at the moment.

```

$ git clone  https://github.com/sickcodes/Docker-OSX

$ cd Docker-OSX

$ docker build -t docker-osx:naked -f Dockerfile.naked .

```


1. Start the macOS installer, this will take some times. If clone repository OpenCorePkg is slow , add this `-v "<USERNAME>/macos/OpenCorePkg:/home/arch/OSX-KVM/OpenCorePkg"` to the command below. But make sure you have clone the repository before https://github.com/acidanthera/opencorepkg

```

$ 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 MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom.plist' \

    -e SHORTNAME=monterey \

    sickcodes/docker-osx:latest    

```


2. In the mean time, get the container id and note the container id

```

$ docker ps

```


3. A qemu screen will appear, click on `macOS Base System`. wait the messages loading is complete.




4. Once at the installer screen is up, then to erase the biggest disk. You can name the disk any name because it is not important. Example `my_macos_vd`.




5. Then reinstall the macOS. Pick the disk that you erase in step 4. This installation will take a long time. Approximately 1hour in my host machine.

6. Inspect the container and get the directory where we will copy out the disk. 
```
$ docker inspect 0a0fdebac3ac | grep Upper
                "UpperDir": "/var/lib/docker/overlay2/11043fba8b6ed2e4ffeaeb8a439d791f03081cd785a9a14e60024dc3e6c4f461/diff",
```

7. Once installation is done, power down the container. 

8. Based on the step 6, the value of `UpperDir`, now copy the `mac_hdd_ng.img` to another directory in your host. Any directory will do. I pick `~/macos/`
```
$ sudo su -
# cd /var/lib/docker/overlay2/11043fba8b6ed2e4ffeaeb8a439d791f03081cd785a9a14e60024dc3e6c4f461/diff
# ls -lh ./home/arch/OSX-KVM/mac_hdd_ng.img
-rw-r--r-- 1 jason jason 37G Jun  2 20:43 ./home/arch/OSX-KVM/mac_hdd_ng.img
# cp ./home/arch/OSX-KVM/mac_hdd_ng.img </home/USERNAME/>/macos/
```

9. Update the file permission to your username correctly. 
```
$ cd ~/macos/
$ sudo chown jason:jason mac_hdd_ng.img
$ chmod 664 mac_hdd_ng.img
```

10. Now start the container using the virtual disk, the local built naked image to finish the OS setup/configuration. It will takes more than 30 minutes to complete at least.

```
docker run -it \
    --device /dev/kvm \
    -p 50922:10022 \
    -v "/home/jason/macos/mac_hdd_ng.img:/image" \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -e "DISPLAY=${DISPLAY:-:0.0}" \
    -e MASTER_PLIST_URL=https://raw.githubusercontent.com/sickcodes/Docker-OSX/master/custom/config-nopicker-custom.plist \
    -e SHORTNAME=monterey \
    docker-osx:naked
```  
to speed up the container, add the below parameters to the command above if your host hardware support it.
```
    -m 10g \
    --cpus="8.0" \
    --gpus all \
    --device /dev/nvidia0 \
    --device /dev/nvidia-uvm \
    --device /dev/nvidia-uvm-tools \
    --device /dev/nvidiactl \
```

11. Once started, get the container id again. After the mac os setup/configuration is finish, then stop the container. Note that during this step, OS reboot is expected.

```
$ docker ps
```




12. Now every time to start the container
```
$ docker start <container id from step 11>
```




It is a pity that the macOS after Monterey does not work. If you managed to make it work, I would like to know and please contact me!