我有一个需求:
- 一方面,我需要在 Docker 容器环境下运行应用(因为有些环境在 Mac 下很难安装配置,并且希望环境干净隔离)。
- 另一方面,容器中的应用又需要进行图形界面的显示。
由于 Docker 容器是命令行的形式,本身不支持图形界面显示,因此我希望 Docker 容器能和我的 Mac 主机上的 GUI 进行连接。
我的 Mac OS X 系统版本是:10.14.2
实现的解决方案
socat 安装
首先用 socat 来解决容器和 Mac 主机 GUI 的通信问题:
brew install socat
xquartz 安装
接下来是处理 X windows system,我们需要安装 Xquartz。可以采用 brew 安装(我没有使用这种方式):
brew install xquartz
由于我的网络极差,里面 git clone 下载不下来,我最终选择进入官网直接安装 dmg(v2.6.1),大概 70M 大小。
安装好了之后需要注销并重新进入 Mac 主机。
xquartz 配置
重启之后我们发现有了环境变量 $DISPLAY。
echo $DISPLAY
/private/tmp/com.apple.launchd.nzm51qjuIW/org.macosforge.xquartz:0
点击应用图标或者命令行输入:
open -a Xquartz
程序坞可以看到有一个 Xquartz 应用:
在这个应用下进行偏好设置,勾选允许从网络客户端连接:
配置之后,此时暂时关闭 Xquartz 应用。
Socat 配置
与其他参考的方法不同,我们在有了 DISPLAY 环境变量之后,才会对 Socat 进行配置,输入:
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
注意这个进程一直是运行状态,不要中断它。
现在重新开启 Xquartz 应用(因为我的实践发现 Xquartz 似乎有可能会占用 6000 端口,如果先开启它的话,上面的命令可能不能正常执行)。
此外 Xquartz 应用需要多点击几次。
容器配置
让我们查看主机 OS 上的 IP 地址:
ifconfig en0
en0: flags=8863mtu 1500 ether 60:30:d4:61:f2:fa inet6 fe80::1021:a4c7:f106:2c02%en0 prefixlen 64 secured scopeid 0x5 inet 192.168.0.106 netmask 0xffffff00 broadcast 192.168.0.255 nd6 options=201 media: autoselect status: active
然后在容器内设置环境变量指向这个 IP 地址(由于退出容器后不会保存环境变量,因此每次进入容器都要执行这个命令):
export DISPLAY=192.168.0.106:0
或者在一开始启动容器时就进行设置:
docker run -e DISPLAY=192.168.0.106:0 [image_id]
这样就配置好了。
测试
简单测试应用
在容器内安装钟表小动画并执行:
sudo apt-get install xarclock xarclock
测试脚本
或者,我们可以在容器内写一个 Python 测试脚本:
1 import matplotlib.pyplot as plt 2 import numpy as np 3 4 x = np.linspace(-1, 1, 50) 5 y = 2 * x 6 7 plt.plot(x, y) 8 plt.show()
运行这个脚本后,成功出来图像:
在实际过程中,运行这个脚本可能会报这样的错误:
XIO: fatal IO error 11 (Resource temporarily unavailable) on X server "192.168.0.106:0" after 382 requests (382 known processed) with 11 events remaining.
我自己的理解是可能 Socat 或者 Xquatz 的有些初始化工作没有完成,多运行几次就会成功跑通,并且比较稳定。
这个问题折腾了半天总算实现,还是比较爽的哦。
原文作者:雨先生
原文链接:https://www.cnblogs.com/noluye/p/11405358.html
许可协议:知识共享署名-非商业性使用 4.0 国际许可协议
参考
- Running GUI’s with Docker on Mac OS X
- Docker有关GUI软件的界面显示设计(Windows 宿主主机)
- 在Mac上尝试用Docker运行一个需要网络的Gui程序
- Run GUI apps in containier in OSX (docker for mac)
- OSX X11 Error cannot open display
- Bring Linux apps to the Mac Desktop with Docker
- Docker容器图形界面显示(运行GUI软件)的配置方法(Ubuntu 宿主主机:未成功,这个方案屏幕出现了崩溃)
- Docker容器运行GUI程序的配置方法(Ubuntu 宿主主机:成功)