实现Mac主机上的Docker容器中的图形界面显示(运行GUI应用)

我有一个需求:

  1. 一方面,我需要在 Docker 容器环境下运行应用(因为有些环境在 Mac 下很难安装配置,并且希望环境干净隔离)。
  2. 另一方面,容器中的应用又需要进行图形界面的显示

由于 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=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 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<PERFORMNUD,DAD>
	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 国际许可协议

参考

原文地址:https://www.cnblogs.com/noluye/p/11405358.html