Docker运行带UI界面的应用,并将它的界面投射到你的Windows电脑
困难:Docker运行带UI界面的App
平时我们用Kubernetes或者Docker运行的App,都是后台类的,比如Web-Server,或者计算任务。App自己并不需要打开窗口,大都是接受请求,然后按要求进行计算,最后返回结果这样。
但是假设你要跑一个有UI界面的App时,比如常见的QT类应用,就会遇到报错:
docker run -it sshipway/xclock
Error: Can't open display:
搜索结果一般告诉你,这是由于DISPLAY变量没有设置。于是我们得了解下,DISPLAY变量的作用。
X11窗口显示规范
X11是一种操作系统UI界面的显示规范,最初是1984年麻省理工学院的研究,之后变成UNIX、类UNIX、以及OpenVMS等操作系统所一致适用的标准化软件工具包及显示架构的运作协议。
所以,目前各种App的界面,都是使用X11规范来显示图形化的。
其中X11协议,由X Server来实现,即你的App连上X Server服务器就行了(当然了,X Server也有权限控制,不是谁都可以“隔空投屏”的)。
具体参考:https://en.wikipedia.org/wiki/X_Window_System
所以Docker跑带界面的App报错,意思为:没有指定X Server在哪里。
Linux系统中DISPLAY变量是干嘛的?
在Linux/Unix类操作系统上,界面显示都使用X11规范。
DISPLAY变量是用来设置将图形显示到何处的。(即你的目标 X Server 在哪里)。
如果你登录的Linux是带UI界面的,那么这个值一般为“:0.0”
如果你登录的Linux没有UI的话,比如SSH到一台Ubuntu的VM里,那么这个值很可能就是空的。
DISPLAY 环境变量格式如下 host:NumA.NumB
host是指投射至哪台主机。如果为本机,则host为空。其他主机,则填对应ip
NumA:
本机时,代表unix socket的路径, 如果为0, 则表示连接到/tmp/.X11-unix/X0 .
远端时,表示端口减去6000的值, 假设NumA为0, 则表示连接到6000端口。
NumB:一般都是0
详情可以参考:https://zhuanlan.zhihu.com/p/93165237
容器App,投射界面至容器所在的Host
根据上面的背景知识。我们知道,想投射界面至本机Host上面,那么需要在容器里面将DISPLAY变量=“Host的DISPLAY变量”。同时,还要将unix socket文件,挂载到容器里面。
即:docker run 参数里面要带上以下2个参数
-v /tmp/.X11-unix:/tmp/.X11-unix #共享本地unix端口
-e DISPLAY=$DISPLAY #修改环境变量DISPLAY
同时,在主机上面,应该将 X Server的权限打开:
xhost +
这样,你的容器应该就可以启动了。
(由于我没有带界面的Linux系统,所实际效果暂无截图)
可参考:https://www.youtube.com/watch?v=cMsIT2otEjA
容器App,投射界面至你的Windows系统
想投射界面至远程Windows系统上面,一样的道理,首先咱们先在Windows上面安装 X11Server。
需要在容器里面将DISPLAY变量=“目标IP:0.0”。具体NumA是几,要看你自己的配置情况,一般情况是0。这样容器App,就会“隔空投屏”到你的Windows电脑上面了。
安装X11 Server
咱们的Windows主机上面要安装X Server软件,这里推荐2个:
(1)VcXsrv Windows X Server
https://sourceforge.net/projects/vcxsrv/files/vcxsrv/
最新版本的,安装有报错。最后我选了 vcxsrv-64.1.20.1.4.installer 这个版本是好用的。
一路默认就行,最后一步这里有2个地方小注意:
- 权限控制,记得打钩。 即允许别人远程投屏。
- 有些App自带的图像lib库太老,不认识X Server。(app启动报错:
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
)
这种情况,启动咱们的X Server时,需设置好兼容模式(即上图第2条)。所以我们可以给Windows系统加了条环境变量,如下图:
(2)MobaXterm
这个启动后,X Server默认就启动了。所以不需要太多配置。
Setting里面可以关注下权限等配置。
启动咱们的带UI的容器App
这里选择一个“时钟显示”的示例App
docker pull sshipway/xclock
docker run -e DISPLAY=10.173.103.40:0.0 -it sshipway/xclock
其中IP地址,就是你的电脑
不出意外,你的Windows系统,会弹出一个窗口,如下:
恭喜,完成任务。
总结
Docker容器运行带UI界面的App的时候,需要在容器里面,指定DISPLAY变量。告诉容器系统,应该把界面投射至哪个目标X Server。
- 点赞
- 收藏
- 关注作者
评论(0)