Docker-OSX · 在 Twitter 上关注 @sickcodes

在 Docker 中以接近原生的性能运行 Mac OS X!X11 转发!iMessage 安全研究!iPhone USB 可用!在 Docker 容器中运行 macOS!
使用 Linux 和 Windows 对 macOS 进行安全研究!
Docker-OSX 现已拥有 Discord 服务器和 Telegram!
Discord 在 #docker-osx 频道中活跃,欢迎任何人前来提问、分享想法等。
点击加入 Discord 服务器 https://discord.gg/sickchat
点击加入 Telegram 服务器 https://t.me/sickcodeschat
或者如果是私密的,请通过 Linkedin 联系: https://www.linkedin.com/in/sickcodes
或者通过 https://sick.codes/contact/
作者
本项目由 Sick.Codes 维护。 (Twitter)
更多致谢信息可在此处找到: https://github.com/sickcodes/Docker-OSX/blob/master/CREDITS.md
此外,所有贡献者的完整列表可在此处找到: https://github.com/sickcodes/Docker-OSX/graphs/contributors
特别感谢 @kholia 维护上游项目,Docker-OSX 正是基于该项目构建的: OSX-KVM。
还要特别感谢 @thenickdude,他维护着有价值的分支 KVM-OpenCore,该分支由 @Leoyzen 发起!
特别感谢 OpenCore 团队: https://github.com/acidanthera/OpenCorePkg。他们精心维护的引导加载程序为 Docker-OSX 用户提供了许多出色的功能 :)
如果你喜欢这个项目,请考虑在此处或上游进行贡献!
Docker-OSX 快速入门
视频设置教程也可在此处找到: https://www.youtube.com/watch?v=wLezYl77Ll8
Windows 用户: 点击此处查看以下说明!
第一次来?试试 初始设置,否则请尝试以下说明以使用 Catalina 或 Big Sur。
有任何问题、想法,或者只是想闲聊?
https://discord.gg/sickchat
发布名称及其版本:
Catalina (10.15) 
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e SHORTNAME=catalina \
sickcodes/docker-osx:latest
# docker build -t docker-osx .
Big Sur (11) 
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e SHORTNAME=big-sur \
sickcodes/docker-osx:latest
# docker build -t docker-osx .
Monterey (12) 
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
# docker build -t docker-osx .
Ventura (13) 
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=ventura \
sickcodes/docker-osx:latest
# docker build -t docker-osx .
Sonoma (14) 
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 CPU='Haswell-noTSX' \
-e CPUID_FLAGS='kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on' \
-e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom-sonoma.plist' \
-e SHORTNAME=sonoma \
sickcodes/docker-osx:latest
# docker build -t docker-osx .
红杉 (15) 
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 CPU='Haswell-noTSX' \
-e CPUID_FLAGS='kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on' \
-e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom-sonoma.plist' \
-e SHORTNAME=sequoia \
sickcodes/docker-osx:latest
# docker build -t docker-osx .
Tahoe (16) 
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 CPU='Haswell-noTSX' \
-e CPUID_FLAGS='kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on' \
-e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom-sonoma.plist' \
-e SHORTNAME=tahoe \
sickcodes/docker-osx:latest
docker build -t docker-osx .
旧系统
High Sierra 
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e SHORTNAME=high-sierra \
sickcodes/docker-osx:latest
# docker build -t docker-osx .
Mojave 
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e SHORTNAME=mojave \
sickcodes/docker-osx:latest
# docker build -t docker-osx .
手动下载镜像并在 Docker 中使用
这是一种特别好的下载容器的方式,以防 Docker 的 CDN(或您的连接)恰好很慢。
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}" \
-e GENERATE_UNIQUE=true \
-e MASTER_PLIST_URL=https://raw.githubusercontent.com/sickcodes/Docker-OSX/master/custom/config-nopicker-custom.plist \
-e SHORTNAME=catalina \
sickcodes/docker-osx:naked
共享目录、共享文件、共享文件夹、挂载文件夹
最简单且最安全的方式是 sshfs
# on Linux/Windows
mkdir ~/mnt/osx
sshfs user@localhost: -p 50922 ~/mnt/osx
# wait a few seconds, and ~/mnt/osx will have full rootfs mounted over ssh, and in userspace
# automated: sshpass -p <password> sshfs user@localhost:/ -p 50922 ~/mnt/osx
(VFIO) iPhone USB 直通 (VFIO)
如果您使用的是笔记本电脑,请参阅下一节 usbfluxd 部分。
如果您使用的是台式机,您可以使用 @Silfalion 的说明:https://github.com/Silfalion/Iphone_docker_osx_passthrough
(USBFLUXD) iPhone USB -> 网络式直通 OSX-KVM Docker-OSX
usbfluxd 的视频设置教程也可在此处获取:https://www.youtube.com/watch?v=kTk5fGjK_PM
此方法在笔记本电脑、PC 等任何设备上均可正常工作!
感谢 @nikias 通过 https://github.com/corellium 提供的 usbfluxd!
这是在 Linux 内部完成的。
在 Linux 上打开 3 个终端
在 Linux 上通过 USB 连接您的设备,允许您使用 https://github.com/corellium/usbfluxd 将 usbmuxd 暴露在端口 5000 上,供同一网络上的另一台系统使用。
确保已安装 usbmuxd、socat 和 usbfluxd。
sudo pacman -S libusbmuxd usbmuxd avahi socat
在 AUR 上可用:https://aur.archlinux.org/packages/usbfluxd/
yay usbfluxd
插入你的 iPhone 或 iPad。
Terminal 1
sudo systemctl start usbmuxd
sudo avahi-daemon
Terminal 2:
# on host
sudo systemctl restart usbmuxd
sudo socat tcp-listen:5000,fork unix-connect:/var/run/usbmuxd
Terminal 3:
sudo usbfluxd -f -n
连接到运行 usbfluxd 的主机
这是在 macOS 内部完成的。
安装 homebrew。
172.17.0.1 通常是 Docker 网桥 IP,即你的 PC,但你可以使用 ip addr 中的任何 IP...
macOS 终端:
# on the guest
brew install make automake autoconf libtool pkg-config gcc libimobiledevice usbmuxd
git clone https://github.com/corellium/usbfluxd.git
cd usbfluxd
./autogen.sh
make
sudo make install
接受 USB over TCP 连接,并显示为本地:
(你可能需要将 172.17.0.1 更改为主机的 IP 地址。例如,检查 ip addr)
# on the guest
sudo launchctl start usbmuxd
export PATH=/usr/local/sbin:${PATH}
sudo usbfluxd -f -r 172.17.0.1:5000
关闭 Xcode 等应用程序并重新打开,你的设备应该会显示出来!
如果你需要在 Linux 上重新开始,请清除当前的 usbfluxd、usbmuxd 和 socat:
sudo killall usbfluxd
sudo systemctl restart usbmuxd
sudo killall socat
使用 https://github.com/sickcodes/osx-optimizer 让容器更快
查看 https://github.com/sickcodes/osx-optimizer 中的命令!
- 跳过 GUI 登录屏幕(风险自负!)
- 在 macOS 上禁用 spotlight 索引,以大幅加快 Virtual Instances 的速度。
- 禁用沉重的登录屏幕壁纸
- 禁用更新(风险自负!)
通过将 /var/lib/docker 移动到外部驱动器、块存储、NFS 或任何其他可想象的位置来增加磁盘空间。
按照下面的教程移动 /var/lib/docker
- 使用服务器的磁盘或 SSD,而不是廉价的大容量物理磁盘存储。
- 块存储、NFS 等。
教程在此:https://sick.codes/how-to-run-docker-from-block-storage/
只有在你愿意清除当前所有 Docker 镜像/层的情况下,才遵循上述教程。
安全模式:暂时禁用 docker,以便你可以暂时移动 Docker 文件夹。
- 在你已经移出镜像之前,不要执行此操作 https://github.com/dulatello08/Docker-OSX/#quick-start-your-own-image-naked-container-image
killall dockerd
systemctl disable --now docker
systemctl disable --now docker.socket
systemctl stop docker
systemctl stop docker.socket
现在,Docker 守护进程已关闭,将 /var/lib/docker 移动到某个位置
然后,将 /var/lib/docker 符号链接到某个位置:
mv /var/lib/docker /run/media/user/some_drive/docker
ln -s /run/media/user/some_drive/docker /var/lib/docker
# now check if /var/lib/docker is working still
ls /var/lib/docker
如果你看到文件夹,则说明成功了。你可以重启 Docker,或者如果你想确保万无一失,可以直接重启系统。
重要通知:
2021-11-14 - 添加了 High Sierra、Mojave
在构建时选择以下其中一项,使用 docker pull 时无关紧要:
--build-arg SHORTNAME=high-sierra
--build-arg SHORTNAME=mojave
--build-arg SHORTNAME=catalina
--build-arg SHORTNAME=big-sur
--build-arg SHORTNAME=monterey
--build-arg SHORTNAME=ventura
--build-arg SHORTNAME=sonoma
技术细节
目前存在多个镜像,每个镜像都有不同的用途(详见下文):
- High Sierra (10.13)
- Mojave (10.14)
- Catalina (10.15)
- Big Sur (11)
- Monterey (12)
- Ventura (13)
- Sonoma (14)
- Auto(预制的 Catalina)
- Naked(使用您自己的 .img)
- Naked-Auto(使用您自己的 .img 并通过 SSH 登录)
High Sierra:
Mojave:
Catalina:
Big Sur:
Monterey 制作你自己的镜像:
Ventura 制作你自己的镜像:
Sonoma 制作你自己的镜像:
预制的 Catalina 系统,由 Sick.Codes 提供:用户名:user,密码:alpine
Naked:自带镜像设置(先使用上述任意一种):
裸车自动:与上述相同,但包含 -e USERNAME 和 -e PASSWORD 以及 -e OSX_COMMANDS="put your commands here"
功能
- 在 Linux 上使用 usbfluxd 通过 iPhone OSX KVM 运行!
- 在 Linux 上运行 macOS Monterey 虚拟机!
- 文件夹共享-
- USB 直通(支持热插拔)
- 已启用 SSH (
localhost:50922) - 如果使用 ./vnc 版本,则已启用 VNC (
localhost:8888) - 通过 序列号生成器! 进行 iMessage 安全研究
- 已启用 X11 转发
- 基于 QEMU + KVM 运行
- 支持 Big Sur、自定义镜像、Xvfb 无头模式
- 你可以使用
docker commit克隆你的容器
要求
- 最低安装需要 20GB+++ 磁盘空间(如果使用 Xcode 则需要 50GB)
- 应在 BIOS 设置中启用虚拟化
- 一个支持 kvm 的 x86_64 主机
- 至少 50 GBs 用于
:auto(一半用于基础镜像,一半用于运行时镜像
待办事项
- 面向安全研究人员的文档
- GPU 加速
- 对 virt-manager 的支持
Docker
基于本仓库内容构建的镜像也可在 Docker Hub 上获取,以便使用:https://hub.docker.com/r/sickcodes/docker-osx
可用 Docker 镜像及其预期用途的完整列表可在 说明 中找到。
Kubernetes
Docker-OSX 支持 Kubernetes。
Kubernetes Helm Chart 和文档可在 helm 目录 下找到。
感谢 cephasara 贡献了这一重要贡献。
支持
小问题与故障
如果您在运行 Docker-OSX 时遇到小问题或有任何疑问,请随时提交 issue。
已解决的问题
不过,在提交 issue 之前,请先查看 已关闭的 issue,并确认您正在使用本仓库的最新版本——您的问题可能已经得到解决!您也可以在下方 此处 的问答部分找到答案。
功能请求与更新
关注 @sickcodes!
专业支持
对于更复杂的需求,我们提供以下支持服务:
- 企业支持、商业支持或常规支持。
- 自定义镜像、自定义脚本、咨询(可按小时计费!)
- 与您或您的开发团队进行一对一交流。
如果您感兴趣,请联系 @sickcodes on Twitter 或点击 此处。
许可证/贡献
Docker-OSX 采用 GPL v3+ 许可证。我们欢迎并非常感谢贡献。事实上,您被允许将 Docker-OSX 作为工具来创建专有软件。
其他基于 Docker/QEMU 的有趣项目
- 使用 Dock Droid 在 Docker 容器中运行 Android
- 在宿主机上完全原生运行 Android!
- 使用 Docker-eyeOS 在 Docker 容器中运行 iOS 12 - https://github.com/sickcodes/Docker-eyeOS
- 使用 Bluebubbles.app 在 Docker 中运行 iMessage 中继 - 入门 wiki
免责声明
如果你认真对待 Apple Security,并且有可能在 Apple Bug Bounty Program 中找到六位数的漏洞赏金,那么你来对地方了!更多说明:Hackintosh、OSX-KVM 或 Docker-OSX 合法吗?
本项目中提及的产品名称、徽标、品牌及其他商标均为其各自商标持有人的财产。这些商标持有人与我们的仓库没有任何关联。他们以任何方式都不赞助或认可本项目。
说明
容器镜像
已经设置好或只是想快速创建一个容器?请查看我们的快速入门,或参见我们容器创建示例部分中的更多用例。
有多种不同的 Docker-OSX 镜像可供选择,适用于不同的用途。
sickcodes/docker-osx:latest- 我只想试用一下。sickcodes/docker-osx:latest- 我想使用 Docker-OSX 在 Xcode 中开发/保护应用(登录 Xcode、Transporter)sickcodes/docker-osx:naked- 我想将 Docker-OSX 用于 CI/CD 相关目的(登录 Xcode、Transporter)
使用 :latest 或 big-sur 创建你的个人镜像。然后,从镜像中拉取该镜像。之后,你将能够复制该镜像并将其导入到 :naked 容器中,以便反复将容器恢复到之前的状态。
-
sickcodes/docker-osx:auto- 我只对使用命令行感兴趣(适用于编译软件或无头使用 Homebrew)。 -
sickcodes/docker-osx:naked- 我需要 iMessage/iCloud 用于安全研究。 -
sickcodes/docker-osx:big-sur- 我想运行 Big Sur。 -
sickcodes/docker-osx:monterey- 我想运行 Monterey。 -
sickcodes/docker-osx:ventura- 我想运行 Ventura。 -
sickcodes/docker-osx:sonoma- 我想运行 Sonoma。 -
sickcodes/docker-osx:high-sierra- 我想运行 High Sierra。 -
sickcodes/docker-osx:mojave- 我想运行 Mojave。
初始设置
在做其他任何事情之前,你需要在 BIOS 中开启硬件虚拟化。具体方法取决于你的特定机器(和 BIOS),但应该很简单。
然后,你需要在主机上安装 QEMU 和其他一些依赖项:
# 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 libguestfs-tools
# CENTOS RHEL FEDORA
sudo yum install libvirt qemu-kvm
然后,启用 libvirt 并加载 KVM 内核模块:
sudo systemctl enable --now libvirtd
sudo systemctl enable --now virtlogd
echo 1 | sudo tee /sys/module/kvm/parameters/ignore_msrs
sudo modprobe kvm
我想在 Windows 上运行 Docker-OSX
使用 WSL2(Windows 11 + Windows 子系统 Linux)可以在 Windows 上运行 Docker-OSX。
你必须安装 build 22000+(21H2 或更高版本)的 Windows 11。
首先,在管理员 powershell 中运行此命令在你的计算机上安装 WSL。更多信息,请查看这里。
这将默认安装 Ubuntu。
wsl --install
你可以使用 wsl -l -v 在 PowerShell 中确认 WSL2 已启用。要查看其他可用的发行版,请使用 wsl -l -o。
如果你之前安装过 WSL1,请升级到 WSL 2。检查此链接以从 WSL1 升级到 WSL2。
WSL 安装完成后,前往 C:/Users/<Your_Name>/.wslconfig 并在文件末尾添加 nestedVirtualization=true(如果文件不存在,请创建它)。有关 .wslconfig 文件的更多信息,请查看此链接。请确保在文件资源管理器选项中已选中“显示隐藏文件”和“显示文件扩展名”。
结果应如下所示:
[wsl2]
nestedVirtualization=true
进入你的 WSL 发行版(在 powershell 中运行 wsl),并使用 kvm-ok 命令检查 KVM 是否已启用。输出应如下所示:
INFO: /dev/kvm exists
KVM acceleration can be used
如果尚未安装,请使用命令 sudo apt -y install bridge-utils cpu-checker libvirt-clients libvirt-daemon qemu qemu-kvm 进行安装。
现在,如果尚未安装,请下载并安装 Docker for Windows。
安装完成后,进入设置并勾选以下 2 个复选框:
General -> "Use the WSL2 based engine";
Resources -> WSL Integration -> "Enable integration with my default WSL distro",
确保已安装 x11-apps。如果未安装,请使用命令 sudo apt install x11-apps -y 进行安装。
最后,有 3 种方式获取视频输出:
- WSLg:这是最简单且易于使用的选项。可能会出现一些问题,例如键盘未完全透传或在桌面上看到第二个鼠标 - WSLg 上的问题 - 但仍推荐此选项。
要使用 WSLg 内置的 X-11 服务器,请将 docker run 命令中的这两行更改为指向 WSLg 的 Docker-OSX。
-e "DISPLAY=${DISPLAY:-:0.0}" \
-v /mnt/wslg/.X11-unix:/tmp/.X11-unix \
或者尝试:
-e "DISPLAY=${DISPLAY:-:0}" \
-v /mnt/wslg/.X11-unix:/tmp/.X11-unix \
对于 Windows 上的 Ubuntu 20.x,请参阅 https://github.com/sickcodes/Docker-OSX/discussions/458
- VNC: 请参阅 VNC 部分 以获取更多信息。你也可以向 qemu 添加 -vnc 参数。通过 VNC 客户端连接到你的 mac 虚拟机。这里有一个操作指南
- 桌面环境: 这将为你提供完整的桌面 Linux 体验,但会占用计算机稍多的资源。这里有一个示例指南,但也有其他帮助设置桌面环境的指南。DE 示例
在创建你的容器时的额外启动说明
-
启动 macOS 基础系统(按 Enter 键)
-
点击
Disk Utility -
擦除最大的磁盘(默认约为 200gb),切勿修改较小的磁盘。 -- 如果你无法点击
erase,你可能需要将磁盘大小减少 1kb -
(可选)使用未使用的空间创建一个分区来容纳操作系统和你的文件,如果你想要限制容量。(对于 Xcode 12,分区至少需要 60gb。)
-
点击
Reinstall macOS -
系统在安装过程中可能需要多次重启
故障排除
常规检查
如果你在启动时遇到困难,这是一个很好的起点,尤其是如果你还不太熟悉 Docker。
只是想快速创建一个容器?查看我们的容器创建示例部分。
更具体/高级的故障排查问题和答案可在 更多问题和答案 中找到。您还应该查看 已关闭的问题。即使您无法在此文档中找到,其他人可能已经得到了类似您问题的解答!
确认您的 CPU 支持虚拟化
参见 初始设置。
Docker 未知服务器操作系统错误
docker: unknown server OS: .
See 'docker run --help'.
这意味着你的 docker 守护进程未运行。
pgrep dockerd 应返回空值
因此,你有几种选择。
sudo dockerd 用于前台运行 Docker。我使用此方式。
或者
sudo systemctl --start dockerd 用于立即启动 dockerd。
或者
sudo systemctl --enable --now dockerd 用于在每次重启时启动 dockerd,并立即启动。
使用更多 CPU 核心/SMP
示例:
-e EXTRA='-smp 6,sockets=3,cores=2'
-e EXTRA='-smp 8,sockets=4,cores=2'
-e EXTRA='-smp 16,sockets=8,cores=2'
注意,与内存不同,CPU 使用率是共享的。因此,你可以将所有 CPU 分配给容器。
确认你的用户属于 Docker 组、KVM 组、libvirt 组
将自己添加到 Docker 组
如果你使用 sudo dockerd 或 dockerd 由 systemd/systemctl 控制,则你必须属于 Docker 组。
如果你不属于 Docker 组:
sudo usermod -aG docker "${USER}"
如有需要,也请将自己添加到 kvm 和 libvirt 组:
sudo usermod -aG libvirt "${USER}"
sudo usermod -aG kvm "${USER}"
另请参阅:初始设置。
Docker 守护进程是否已启用?
# run ad hoc
sudo dockerd
# or daemonize it
sudo nohup dockerd &
# enable it in systemd (it will persist across reboots this way)
sudo systemctl enable --now docker
# or just start it as your user with systemd instead of enabling it
systemctl start docker
更多问题与解答
衷心感谢我们的贡献者,他们迄今为止已经解决了几乎所有可预见的问题!
https://github.com/sickcodes/Docker-OSX/blob/master/CREDITS.md
稍后启动同一容器(持久化磁盘)
使用 docker run 创建了一个容器,并希望稍后再次复用其底层镜像?
注意:请先参阅 容器创建示例,了解如何到达适用此场景的状态。
这适用于您希望稍后再次运行同一个容器的情况。您可能需要使用 docker commit 在复用之前保存您的容器。使用 docker ps --all 检查您的容器是否已持久化。
如果您不执行此操作,每次都会生成一个新的镜像。
# look at your recent containers and copy the CONTAINER ID
docker ps --all
# docker start the container ID
docker start -ai 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"
你也可以将 .img 文件从容器中提取出来,该文件存储在 /var/lib/docker 中,并将其作为运行时参数提供给 :naked Docker 镜像。
另请参阅:此处。
我之前使用过 Docker-OSX,并希望重启一个自动启动的容器
使用 sickcodes/docker-osx:auto 的容器可以在启动过程中被停止。
# find last container
docker ps -a
# docker start old container with -i for interactive, -a for attach STDIN/STDOUT
docker start -ai -i <Replace this with your ID>
LibGTK 错误 "connection refused"
如果您尚未完成硬件虚拟化的所有配置,可能会看到一个或多个与 libgtk 相关的错误。如果您尚未完成,请查看 initial setup 部分和 routine checks 部分,您可能遗漏了某个配置步骤,或者尚未准备好所有必需的 Docker 依赖项。
另请参阅:here。
Permissions denied 错误
如果您尚未配置 xhost,请尝试以下操作:
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 +
RAM 超额分配
你无法分配超过机器实际拥有的 RAM。默认值为 3 Gigabytes:-e RAM=3。
如果你尝试为容器分配超过当前可用量的 RAM,可能会看到如下错误:cannot set up guest memory 'pc.ram': Cannot allocate memory。另请参阅:此处,此处。
例如(如下所示),buff/cache 中已包含 20 Gigabytes 的已分配 RAM:
[user@hostname ~]$ free -mh
total used free shared buff/cache available
Mem: 30Gi 3.5Gi 7.0Gi 728Mi 20Gi 26Gi
Swap: 11Gi 0B 11Gi
清除缓冲区与缓存:
sudo tee /proc/sys/vm/drop_caches <<< 3
现在再次检查 RAM:
[user@hostname ~]$ free -mh
total used free shared buff/cache available
Mem: 30Gi 3.3Gi 26Gi 697Mi 1.5Gi 26Gi
Swap: 11Gi 0B 11Gi
PulseAudio
使用 PulseAudio 处理声音
注意:AppleALC、alcid 和 VoodooHDA-OC 不支持 codec。然而,IORegistryExplorer 确实显示控制器组件正在工作。
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 调试
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
使用 WSLg 的 PulseAudio
docker run \
--device /dev/kvm \
-e AUDIO_DRIVER=pa,server=unix:/tmp/pulseaudio.socket \
-v /mnt/wslg/runtime-dir/pulse/native:/tmp/pulseaudio.socket \
-v /mnt/wslg/.X11-unix:/tmp/.X11-unix \
sickcodes/docker-osx
转发额外端口(nginx 托管示例)
根据您的需求,可以转发额外的端口。在本示例中,我们将使用 Mac OSX 来托管 nginx:
host:10023 <-> 10023:container:10023 <-> 80:guest
在主机上,运行:
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-e ADDITIONAL_PORTS='hostfwd=tcp::10023-:80,' \
-p 10023:10023 \
sickcodes/docker-osx:auto
在运行容器的 Terminal 会话中,执行:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install nginx
sudo sed -i -e 's/8080/80/' /usr/local/etc/nginx/nginx.confcd
# sudo nginx -s stop
sudo nginx
nginx 现在应该可以在端口 10023 上访问。
此外,你可以将多条语句串联在一起,例如:
-e ADDITIONAL_PORTS='hostfwd=tcp::10023-:80,hostfwd=tcp::10043-:443,'
-p 10023:10023 \
-p 10043:10043 \
桥接网络
您可能无需对默认配置进行任何操作即可启用容器内部的互联网连接。此外,即使 ping 不起作用,curl 也可能正常工作。
为远程安装的桥接网络连接启用 IPv4 转发
本地安装不需要此操作。
此外请注意,即使您在容器中使用 VPN,这也可能导致主机泄露您的 IP。
但是,如果您正在尝试远程连接到 Docker-OSX 实例(例如托管在数据中心中的 Docker-OSX 实例),这可能会提高您的性能:
# 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 <<EOF
net.ipv4.ip_forward = 1
EOF
# or edit manually with the editor of your choice
nano /etc/sysctl.conf || vi /etc/sysctl.conf || vim /etc/sysctl.conf
# now reboot
与 Docker-OSX QEMU macOS 共享文件夹
与来宾系统共享文件夹非常简单。
您的文件夹将进入 Arch 容器内的 /mnt/hostshare,然后通过 QEMU 传递。
然后在 mac 内部使用 sudo -S mount_9p hostshare 进行挂载。
例如,
FOLDER=~/somefolder
-v "${FOLDER}:/mnt/hostshare" \
-e EXTRA="-virtfs local,path=/mnt/hostshare,mount_tag=hostshare,security_model=passthrough,id=hostshare" \
完整示例:
# stat mac_hdd_ng.img
SHARE=~/somefolder
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-v "${PWD}/mac_hdd_ng.img:/home/arch/OSX-KVM/mac_hdd_ng.img" \
-v "${SHARE}:/mnt/hostshare" \
-e EXTRA="-virtfs local,path=/mnt/hostshare,mount_tag=hostshare,security_model=passthrough,id=hostshare" \
sickcodes/docker-osx:latest
# !!! Open Terminal inside macOS and run the following command to mount the virtual file system
# sudo -S mount_9p hostshare
将 Linux NFS 驱动器共享到 macOS
要通过 NFS 共享文件夹,请在主机上设置一个文件夹,例如 /srv/nfs/share,然后将其追加到 /etc/exports:
/srv/nfs/share 127.0.0.1/0(insecure,rw,all_squash,anonuid=1000,anongid=985,no_subtree_check)
您可能需要现在重新加载导出,这将开始共享该目录。
# reload shared folders
sudo exportfs -arv
为 anonuid 和 anongid 授予共享文件夹的权限,其中 anonuid 和 anongid 需与您的 linux 用户相匹配;id -u
id -u ; id -g 将输出 userid:groupid
chown 1000:985 /srv/nfs/share
chmod u+rwx /srv/nfs/share
使用附加标志 --network host 启动 Docker-OSX 容器
在 mac 终端中创建并挂载 nfs 文件夹:
mkdir -p ~/mnt
sudo mount_nfs -o locallocks 10.0.2.2:/srv/nfs/share ~/mnt
通过 QEMU 将 USB 驱动器共享到 macOS
挂载 USB 驱动器(热插拔/热插 USB)
启动您的容器。
选择一个端口,例如,7700。
lsusb 以获取 vid:pid
在 Linux 上:
sudo usbredirserver -p 7700 1e3d:2096
现在,在 Docker 窗口中按 Enter 键以查看 (qemu) 控制台。
即使机器已启动,您也可以使用如下命令添加/移除磁盘:
chardev-add socket,id=usbredirchardev1,port=7700,host=172.17.0.1
device_add usb-redir,chardev=usbredirchardev1,id=usbredirdev1,debug=4
在 macOS 启动时挂载 USB 驱动器到 Docker OSX
PORT=7700
IP_ADDRESS=172.17.0.1
-e EXTRA="-chardev socket,id=usbredirchardev1,port=${PORT},host=${IP_ADDRESS} -device usb-redir,chardev=usbredirchardev1,id=usbredirdev1,debug=4" \`
Fedora:通过桥接网络启用互联网连接
Fedora 的默认防火墙设置可能会阻止 Docker 的网络接口访问互联网。为了解决此问题,你需要在防火墙中将该接口加入白名单:
# Set the docker0 bridge to the trusted zone
sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0
sudo firewall-cmd --reload
嵌套硬件虚拟化
检查您的机器是否已启用硬件虚拟化:
sudo tee /sys/module/kvm/parameters/ignore_msrs <<< 1
egrep -c '(svm|vmx)' /proc/cpuinfo
虚拟网络适配器
快速互联网连接
-e NETWORKING=vmxnet3
互联网连接缓慢
-e NETWORKING=e1000-82545em
CI/CD 相关改进
减小镜像大小的技巧
- 像往常一样启动容器,并删除不必要的文件。一种有用的
方法是使用
du -sh *从/目录开始,并查找 可以删除文件的大目录。例如不必要的缓存文件、 Xcode 平台等。 - 一旦你对释放的空间量感到满意,使用
sudo trimforce enable启用 trim,然后重启。 - 使用
dd if=/dev/zero of=./empty && rm -f empty将磁盘上的空闲空间清零 - 关闭虚拟机并使用
docker cp stoppedcontainer:/home/arch/OSX-KVM/mac_hdd_ng.img .复制出 qcow 镜像 - 运行
qemu-img check -r all mac_hdd_ng.img以修复任何错误。 - 运行
qemu-img convert -O qcow2 mac_hdd_ng.img deduped.img并再次检查错误 - 可选: 运行
qemu-img convert -c -O qcow2 deduped.img compressed.img以进一步压缩镜像。这可能会降低运行时速度,但应将大小减少约 25%。 - 再次检查错误,并构建一个新的 docker 镜像。例如使用此 Dockerfile
FROM sickcodes/docker-osx
USER arch
COPY --chown=arch ./deduped.img /home/arch/OSX-KVM/mac_hdd_ng.img
使用 Telnet 无头运行 Docker-OSX
首先确保 autoboot 已启用
接下来,你需要设置 SSH 以自动启动。
sudo systemsetup -setremotelogin on
确保提交新的 docker 镜像并保存,或按照减少磁盘空间]一节中的说明重新构建。
然后使用以下参数运行它。
# 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" \
mycustomimage
在本地构建 Docker-OSX 时,使用哪些镜像源是合适的?
如果你要在本地构建 Docker-OSX,你可能希望使用 Arch Linux 的镜像源。
镜像源位置可在此处找到(使用两位国家代码):https://archlinux.org/mirrorlist/all/
docker build -t docker-osx:latest \
--build-arg RANKMIRRORS=true \
--build-arg MIRROR_COUNTRY=US \
--build-arg MIRROR_COUNT=10 \
--build-arg SHORTNAME=catalina \
--build-arg SIZE=200G .
自定义 QEMU 参数(直通设备)
使用便捷的运行时参数提供程序选项 -e EXTRA=,将任意设备/目录传递给 Docker 容器及 QEMU 参数。
# example customizations
docker run \
-e RAM=4 \
-e SMP=4 \
-e CORES=4 \
-e EXTRA='-usb -device usb-host,hostbus=1,hostaddr=8' \
-e INTERNAL_SSH_PORT=23 \
-e MAC_ADDRESS="$(xxd -c1 -p -l 6 /dev/urandom | tr '\n' ':' | cut -c1-17)" \
-e AUDIO_DRIVER=alsa \
-e IMAGE_PATH=/image \
-e SCREEN_SHARE_PORT=5900 \
-e DISPLAY=:0 \
-e NETWORKING=vmxnet3 \
--device /dev/kvm \
--device /dev/snd \
-v /tmp/.X11-unix:/tmp/.X11-unix \
docker-osx:latest
生成序列号
在 ./custom 中生成序列号,或者让 docker 在运行时生成它们(见下文)。
在任何时候,登录 iCloud 等之前,请验证您的序列号。
# this is a quick way to check your serial number via cli inside OSX
ioreg -l | grep IOPlatformSerialNumber
# test some commands
sshpass -p 'alpine' ssh user@localhost -p 50922 'ping google.com'
# check your serial number
sshpass -p 'alpine' ssh user@localhost -p 50922 'ioreg -l | grep IOPlatformSerialNumber'
开始使用序列号
# ARCH
pacman -S libguestfs
# UBUNTU DEBIAN
apt install libguestfs -y
# RHEL FEDORA CENTOS
yum install libguestfs -y
在 ./custom 文件夹中,您将找到 4 脚本。
config-nopicker-custom.plistopencore-image-ng.sh
这两个文件来自 OSX-KVM。
你不需要修改这两个文件。
config.plist 中有 5 个值被替换为占位符。点击此处查看这些值,没有理由。
generate-unique-machine-values.sh此脚本将生成序列号,附带 Mac 地址,并输出到 CSV/TSV,同时生成一个bootdisk image。
你可以创建数百个,./custom/generate-unique-machine-values.sh --help
./custom/generate-unique-machine-values.sh \
--count 1 \
--tsv ./serial.tsv \
--bootdisks \
--output-bootdisk OpenCore.qcow2 \
--output-env source.env.sh
或者,如果你有一些特定的序列号……
generate-specific-bootdisk.sh
generate-specific-bootdisk.sh \
--model "${DEVICE_MODEL}" \
--serial "${SERIAL}" \
--board-serial "${BOARD_SERIAL}" \
--uuid "${UUID}" \
--mac-address "${MAC_ADDRESS}" \
--output-bootdisk OpenCore-nopicker.qcow2
此示例在运行时以无头模式生成一组随机序列号
# proof of concept only, generates random serial numbers, headlessly, and quits right after.
docker run --rm -it \
--device /dev/kvm \
-p 50922:10022 \
-e NOPICKER=true \
-e GENERATE_UNIQUE=true \
-e DEVICE_MODEL="iMacPro1,1" \
sickcodes/docker-osx:auto
# -e OSX_COMMANDS='ioreg -l | grep IOPlatformSerialNumber' \
此示例在运行时生成一组特定的序列号
# run the same as above 17gb auto image, with SSH, with nopicker, and save the bootdisk for later.
# you don't need to save the bootdisk IF you supply specific serial numbers!
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-e NOPICKER=true \
-e GENERATE_SPECIFIC=true \
-e DEVICE_MODEL="iMacPro1,1" \
-e SERIAL="C02TW0WAHX87" \
-e BOARD_SERIAL="C027251024NJG36UE" \
-e UUID="5CCB366D-9118-4C61-A00A-E5BAF3BED451" \
-e MAC_ADDRESS="A8:5C:2C:9A:46:2F" \
-e OSX_COMMANDS='ioreg -l | grep IOPlatformSerialNumber' \
sickcodes/docker-osx:auto
此示例在运行时使用您现有的图像,以 1000x1000 显示分辨率生成一组特定的序列号
# run an existing image in current directory, with a screen, with SSH, with nopicker.
stat mac_hdd_ng.img # make sure you have an image if you're using :naked
docker run -it \
-v "${PWD}/mac_hdd_ng.img:/image" \
--device /dev/kvm \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-p 50922:10022 \
-e NOPICKER=true \
-e GENERATE_SPECIFIC=true \
-e DEVICE_MODEL="iMacPro1,1" \
-e SERIAL="C02TW0WAHX87" \
-e BOARD_SERIAL="C027251024NJG36UE" \
-e UUID="5CCB366D-9118-4C61-A00A-E5BAF3BED451" \
-e MAC_ADDRESS="A8:5C:2C:9A:46:2F" \
-e WIDTH=1000 \
-e HEIGHT=1000 \
sickcodes/docker-osx:naked
如果你想生成序列号,可以在运行时使用
-e GENERATE_UNIQUE=true \
或者你可以在 ./custom 文件夹中生成它们。然后使用:
-e GENERATE_SPECIFIC=true \
-e SERIAL="" \
-e BOARD_SERIAL="" \
-e UUID="" \
-e MAC_ADDRESS="" \
使序列号在重启后持久化
stat mac_hdd_ng_testing.img
touch ./output.env
# generate fresh random serial numbers, with a screen, using your own image, and save env file with your new serial numbers for later.
docker run -it \
--device /dev/kvm \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-p 50922:10022 \
-e NOPICKER=true \
-e GENERATE_UNIQUE=true \
-e GENERATE_SPECIFIC=true \
-e DEVICE_MODEL="iMacPro1,1" \
-v "${PWD}/output.env:/env" \
-v "${PWD}/mac_hdd_ng_testing.img:/image" \
sickcodes/docker-osx:naked
要使用 iMessage 或 iCloud,您需要更改 5 值。
SERIALBOARD_SERIALUUIDMAC_ADDRESS
ROM 只是小写的 mac 地址,每个单词之间没有 :。
你可以让容器为你生成它们,使用 -e GENERATE_UNIQUE=true
或者让容器使用特定的值,使用 -e GENERATE_SPECIFIC=true
-e GENERATE_SPECIFIC=true \
-e DEVICE_MODEL="iMacPro1,1" \
-e SERIAL="C02TW0WAHX87" \
-e BOARD_SERIAL="C027251024NJG36UE" \
-e UUID="5CCB366D-9118-4C61-A00A-E5BAF3BED451" \
-e MAC_ADDRESS="A8:5C:2C:9A:46:2F" \
更改显示分辨率
显示分辨率由以下行控制:
https://github.com/sickcodes/Docker-OSX/blob/master/custom/config-nopicker-custom.plist#L819
Docker-OSX 不会挂载该磁盘,而是使用这个巧妙的技巧生成一个新的 OpenCore.qcow2:
-e GENERATE_UNIQUE=true \
-e WIDTH=800 \
-e HEIGHT=600 \
要使用 WIDTH/HEIGHT,必须与 -e GENERATE_UNIQUE=true 或 -e GENERATE_SPECIFIC=true 一起使用。
由于需要使用 libguestfs 创建新的启动分区,启动时间将延长约 30 秒。
-e GENERATE_SPECIFIC=true \
-e WIDTH=1920 \
-e HEIGHT=1080 \
-e SERIAL="" \
-e BOARD_SERIAL="" \
-e UUID="" \
-e MAC_ADDRESS="" \
更改 Docker-OSX 分辨率示例
# using an image in your current directory
stat 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}" \
-e GENERATE_SPECIFIC=true \
-e DEVICE_MODEL="iMacPro1,1" \
-e SERIAL="C02TW0WAHX87" \
-e BOARD_SERIAL="C027251024NJG36UE" \
-e UUID="5CCB366D-9118-4C61-A00A-E5BAF3BED451" \
-e MAC_ADDRESS="A8:5C:2C:9A:46:2F" \
-e MASTER_PLIST_URL=https://raw.githubusercontent.com/sickcodes/Docker-OSX/master/custom/config-nopicker-custom.plist \
-e WIDTH=1600 \
-e HEIGHT=900 \
sickcodes/docker-osx:naked
# generating random serial numbers, using the DIY installer, along with the screen resolution changes.
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 WIDTH=800 \
-e HEIGHT=600 \
sickcodes/docker-osx:latest
这里还有几种其他分辨率!如果你的分辨率无效,它将默认为 800x600。
-e WIDTH=800 \
-e HEIGHT=600 \
-e WIDTH=1280 \
-e HEIGHT=768 \
-e WIDTH=1600 \
-e HEIGHT=900 \
-e WIDTH=1920 \
-e HEIGHT=1080 \
-e WIDTH=2560 \
-e HEIGHT=1600 \
本示例展示了如何在容器创建后更改分辨率。
第一步是停止 docker 守护进程
sudo systemctl stop docker
第二步是修改容器配置
/var/lib/docker/containers/[container-id]/config.v2.json
(假设你原始的 WIDTH 为 1024,HEIGHT 为 768,你可以搜索 1024 并将其替换为新值。768 同理。)
最后一步是重启 docker 守护进程
sudo systemctl restart docker
在 Mac OSX 中挂载物理磁盘
将磁盘作为卷传入容器,然后再次将磁盘传入 QEMU 命令行附加参数中。
使用 config-custom.plist,因为你可能希望看到启动菜单,否则省略第一行:
DISK_TWO="${PWD}/mount_me.img"
-e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom.plist' \
-v "${DISK_TWO}:/disktwo" \
-e EXTRA='-device ide-hd,bus=sata.5,drive=DISK-TWO -drive id=DISK-TWO,if=none,file=/disktwo,format=qcow2' \
物理磁盘挂载示例
OSX_IMAGE="${PWD}/mac_hdd_ng_xcode_bigsur.img"
DISK_TWO="${PWD}/mount_me.img"
docker run -it \
--device /dev/kvm \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom.plist' \
-v "${OSX_IMAGE}":/image \
-v "${DISK_TWO}":/disktwo \
-e EXTRA='-device ide-hd,bus=sata.5,drive=DISK-TWO -drive id=DISK-TWO,if=none,file=/disktwo,format=qcow2' \
sickcodes/docker-osx:naked
另请参阅:此处。
在 Linux 上提取 APFS 磁盘
在 Docker-OSX 中,我们使用的是 qcow2 镜像。
这意味着镜像会随着你的使用而增长,但客户机操作系统认为你有 200GB 可用空间。
只读
# mount the qemu image like a real disk
sudo modprobe nbd max_part=8
sudo qemu-nbd --connect=/dev/nbd0 ./image.img
sudo fdisk /dev/nbd0 -l
mkdir -p ./mnt
sudo mount /dev/nbd0p1 ./mnt
# inspect partitions (2 partitions)
sudo fdisk /dev/nbd0 -l
# mount using apfs-linux-rw OR apfs-fuse
mkdir -p ./part
sudo mount /dev/nbd0p2 ./part
sudo apfs-fuse -o allow_other /dev/nbd0p2 ./part
当您完成对磁盘的检查后,可以卸载分区、磁盘并移除回环设备:
sudo umount ./part
sudo umount ./mnt
sudo qemu-nbd --disconnect /dev/nbd0
sudo rmmod nbd
USB 直通
首先,QEMU 必须以 root 身份启动。
通过更改容器内设备的权限,也有可能实现 USB 直通。 参见 此处。
例如,使用以下内容创建一个新的 Dockerfile
FROM sickcodes/docker-osx
USER arch
RUN sed -i -e s/exec\ qemu/exec\ sudo\ qemu/ ./Launch.sh
COPY --chown=arch ./new_image.img /home/arch/OSX-KVM/mac_hdd_ng.img
其中 new_image.img 是您提取的 qcow2 镜像。然后使用 docker build . 进行重建
接下来,我们需要找出要传递给虚拟机的 USB 设备的总线和端口号:
lsusb -t
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/6p, 5000M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/12p, 480M
|__ Port 2: Dev 5, If 0, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 2: Dev 5, If 1, Class=Chip/SmartCard, Driver=, 12M
|__ Port 3: Dev 2, If 0, Class=Wireless, Driver=, 12M
|__ Port 3: Dev 2, If 1, Class=Wireless, Driver=, 12M
|__ Port 5: Dev 3, If 0, Class=Video, Driver=uvcvideo, 480M
|__ Port 5: Dev 3, If 1, Class=Video, Driver=uvcvideo, 480M
在本示例中,我们想要透传一个智能卡设备。我们想要的设备位于总线 1 和端口 2。
如果你的设备是 usb 2.0 (ehci) 与 usb 3.0 (xhci),也可能存在差异。 参见 此处 以获取更多详细信息。
# hostbus and hostport correspond to the numbers from lsusb
# runs in privileged mode to enable access to the usb devices.
docker run \
--privileged \
--device /dev/kvm \
-e RAM=4 \
-p 50922:10022 \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e EXTRA="-device virtio-serial-pci -device usb-host,hostbus=1,hostport=2" \
mycustomimage
在 MacOS shell 中执行 system_profiler SPUSBDataType 时,你应该能看到设备出现。
重要提示:在虚拟机运行期间,这将导致主机系统失去对该 USB 设备的访问权限!
容器创建示例
快速启动你自己的镜像(裸容器镜像)
这是我最喜欢的容器。你可以提供一个现有的磁盘镜像作为 Docker 命令行参数。
-
使用
sudo find /var/lib/docker -name mac_hdd_ng.img -size +10G拉取镜像 -
使用命令参数
-v "${PWD}/mac_hdd_ng.img:/image"提供你自己的本地镜像,并在指示 Docker 创建容器时使用sickcodes/docker-osx:naked。-
裸镜像用于启动任何现有的 .img 文件,例如当前工作目录中的文件(
$PWD) -
默认情况下,此镜像有一个名为
NOPICKER的变量,其值为"true"。这会跳过磁盘选择菜单。使用-e NOPICKER=false或除单词true以外的任何字符串来进入启动菜单。这允许你使用其他磁盘,而不是跳过启动菜单,例如恢复磁盘或磁盘工具。
-
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
构建具有视频输出的 OSX 容器
快速入门命令应开箱即用,前提是您保留以下行。适用于 auto 和 naked 机器:
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
带有任意命令行参数的预构建镜像
-e OSX_COMMANDS 允许你在容器内运行任何命令
docker pull sickcodes/docker-osx:auto
# boot to OS X shell + display + specify commands to run inside OS X!
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 \"put your commands here\"" \
sickcodes/docker-osx:auto
# Boots in a minute or two!
或者,如果你已经拥有一张图片,并且只想登录并执行任意命令:
docker pull sickcodes/docker-osx:naked-auto
# boot to OS X shell + display + specify commands to run inside OS X!
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e USERNAME=yourusername \
-e PASSWORD=yourpassword \
-e "OSX_COMMANDS=/bin/bash -c \"put your commands here\"" \
sickcodes/docker-osx:naked-auto
# Boots in a minute or two!
更多示例
存在大量其他潜在用例,它们可以与 Docker-OSX 完美配合,其中一些将在下文展示!
构建无头 OSX 容器
对于无头容器,请从您的 docker run 命令中删除以下两行:
# -v /tmp/.X11-unix:/tmp/.X11-unix \
# -e "DISPLAY=${DISPLAY:-:0.0}" \
从自定义镜像构建无头容器
这对于 CI/CD 流水线尤其有帮助。
# 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
构建一个允许在 localhost 上使用不安全 VNC 的无头容器(!仅限本地使用!)
必须将 -it 更改为 -i,才能与 QEMU 控制台进行交互
要退出使用 -i 的容器,你必须 docker kill <containerid>。例如,要终止所有进程,docker ps | xargs docker kill。
原生 QEMU VNC 示例
docker run -i \
--device /dev/kvm \
-p 50922:10022 \
-p 5999:5999 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e EXTRA="-display none -vnc 0.0.0.0:99,password=on" \
sickcodes/docker-osx:big-sur
# type `change vnc password myvncusername` into the docker terminal and set a password
# connect to localhost:5999 using VNC
# qemu 6 seems to require a username for vnc now
完全没有使用 TLS/HTTPS 加密!
或者 ssh -N root@1.1.1.1 -L 5999:127.0.0.1:5999,其中 1.1.1.1 是你的远程服务器 IP。
(注意:如果你关闭端口 5999 并使用 SSH 隧道,这就变得安全了。)
构建一个无头容器以通过安全 VNC 远程运行
添加以下行:
-e EXTRA="-display none -vnc 0.0.0.0:99,password=on"
在 Docker 终端中,按 enter 直到看到 (qemu)。
输入 change vnc password someusername
为你的新 vnc 用户名^ 设置一个密码。
你还需要容器 IP:docker inspect <containerid> | jq -r '.[0].NetworkSettings.IPAddress'
或者 ip n 通常会首先显示容器 IP。
现在 VNC 使用 Docker 容器 IP 进行连接,例如 172.17.0.2:5999
通过 SSH 进行远程 VNC:ssh -N root@1.1.1.1 -L 5999:172.17.0.2:5999,其中 1.1.1.1 是你的远程服务器 IP,172.17.0.2 是你的局域网容器 IP。
现在你可以直接通过 VNC 连接到任何使用此命令构建的容器!
我想使用 SPICE 而不是 VNC
可选地,你可以启用 SPICE 协议,它允许使用 remote-viewer 访问你的 OSX 容器,而不是 VNC。
注意:-disable-ticketing 将允许未经身份验证的访问 VM。请参阅 spice 手册 以获取设置身份验证访问(“Ticketing”)的帮助。
docker run \
--device /dev/kvm \
-p 3001:3001 \
-p 50922:10022 \
-e "DISPLAY=${DISPLAY:-:0.0}" \
-e EXTRA="-monitor telnet::45454,server,nowait -nographic -serial null -spice disable-ticketing,port=3001" \
mycustomimage
然后只需执行 remote-viewer spice://localhost:3001 并添加 --spice-debug 用于调试。
基于已配置和设置好的容器创建镜像
# 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
docker pull sickcodes/docker-osx:auto
# boot directly into a real OS X shell with no display (Xvfb) [HEADLESS]
docker run -it \
--device /dev/kvm \
-p 50922:10022 \
sickcodes/docker-osx:auto
# username is user
# password is alpine
# Wait 2-3 minutes until you drop into the shell.
运行 Docker-OSX 的原始版本
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?
运行但在 OS X 中启用 SSH(原始版本)!
docker run -it \
--device /dev/kvm \
--device /dev/snd \
-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 OS X in the "Sharing" settings.
ssh user@localhost -p 50922
安装完所有内容后自动启动 OS X
添加额外选项 -e NOPICKER=true。
旧机器:
# find your 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
"
安装后 big-sur 镜像启动缓慢。这是预期行为吗?
容器设置中的自动更新仍处于开启状态。您可能希望将其关闭。我们对此有未来的开发计划。
什么是 ${DISPLAY:-:0.0}?
$DISPLAY 是指向您的 X11 显示服务器的 shell 变量。
${DISPLAY} 的作用相同,但允许您像这样连接变量:
- 例如,
${DISPLAY}_${DISPLAY}会打印:0.0_:0.0 - 例如,
$DISPLAY_$DISPLAY会打印:0.0
...因为 $DISPLAY_ 不是 $DISPLAY
${variable:-fallback} 允许您设置一个“回退”变量,当 $variable 未设置时进行替换。
您还可以使用 ${variable:=fallback} 来设置该变量(在您当前的终端中)。
在 Docker-OSX 中,我们假设 :0.0 是您的默认 $DISPLAY 变量。
您可以查看您的
echo $DISPLAY
这样,${DISPLAY:-:0.0} 将使用你的 X11 服务器为你设置的任何变量,否则 :0.0
什么是 -v /tmp/.X11-unix:/tmp/.X11-unix?
-v 是一个 Docker 命令行选项,允许你将一个卷传递给容器。
我们让 Docker 容器使用的目录是一个 X 服务器显示套接字。
/tmp/.X11-unix
如果我们让 Docker 容器使用与我们自身环境相同的显示套接字,那么在 Docker 容器内运行的任何应用程序也会显示在你的屏幕上!https://www.x.org/archive/X11R6.8.0/doc/RELNOTES5.html
启动或创建容器时出现 ALSA 错误
在初始化或启动进入容器时,你可能会在 (qemu) 控制台中看到如下形式的错误:
ALSA lib blahblahblah: (function name) returned error: no such file or directory。这些错误或多或少是预期之中的。只要你能启动进入容器且一切运行正常,就没有理由为此担心。
另请参阅:此处。

