当图像在 docker 机器中运行时,X11 转发不起作用,但如果图像在没有 docker 机器的情况下运行,则它可以正常工作

Posted

技术标签:

【中文标题】当图像在 docker 机器中运行时,X11 转发不起作用,但如果图像在没有 docker 机器的情况下运行,则它可以正常工作【英文标题】:X11 forwarding doesn’t work when image runs in docker machine but it works fine if the image is run w/o a docker machine 【发布时间】:2018-10-18 14:01:45 【问题描述】:

我有一个基于 debian 的 docker 容器,当我运行它时它可以工作,

“docker run -ti --name devworkstation --rm --net=host -v /var/run/docker.sock:/var/run/docker.sock -e DISPLAY=$env:DISPLAY xxxx/xxxx:devworkstation”

通过工作,我的意思是 bash 命令提示符出现,当我运行 xeyes 时,我看到了我的 Windows 10 计算机上的窗口,正如我所期望的那样。 (x11 转发工作。)

($env:DISPLAY = “myWinIP:0.0”)

然后,我创建了一个名为“dockerExternalSwitch”的新外部虚拟交换机和一个带有“docker-machine create -d hyperv --hyperv-virtual-switch dockerExternalSwitch dev1”的 docker 机器

我根据 docker-machine env dev1 设置了我的环境。然后我在 docker 机器上运行与上面相同的 docker run 命令。它会按我的预期显示我的命令提示符,但是当我运行 xeyes 时,出现错误:

错误:无法打开显示:xxx.xxx.xxx.xxx:0.0

我还在 debian 映像上安装了 firefox。它给出了类似的错误: 无法初始化服务器:不支持百老汇显示类型:xxx.xx.xx.xxx:0.0 错误:无法打开显示:xxx.xxx.xxx.xxx:0.0

因为当我直接运行它(没有 docker 机器)时它可以工作,而当我使用 docker 机器时它会失败,我想知道它是否与网络有关。

Dockerfile 内容:

from debian:9.5
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y firefox-esr
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y vim git curl
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y build-essential
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y gdb valgrind
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y qt4-default
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y dos2unix tcpdump netcat
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y apt-utils
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y linux-image-rt-amd64
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y task-mate-desktop
RUN env
CMD /bin/bash

我已经尝试了所有可以在互联网上找到的 x11 转发建议。我已经在堆栈溢出中搜索了建议。我还没有找到解决方案,它似乎与 docker 机器有关。任何关于我可以尝试的建议将不胜感激。

(仅供参考,我使用 docker-machine 的原因是我有示例代码可以连接到作为 docker-machine 工作的网络摄像头,但当我在没有 docker-machine 的情况下运行时却没有。)

【问题讨论】:

【参考方案1】:

我想通了。在不使用 docker 机器运行映像时,DISPLAY 变量必须是我的 windows 计算机的 ip 地址。使用 docker 机器运行映像时,我必须将 DISPLAY 环境变量更改为我创建的新虚拟交换机的 IP 地址。在我的脚本文件中,我使用了以下代码:

#$local is true when running w/o the docker machine
if ($local) 
     $IPv4=get-netipaddress -InterfaceAlias "vEthernet (Default Switch)" -AddressFamily "IPv4" | select -expand IPAddress
 
 else 
     $IPv4=get-netipaddress -InterfaceAlias "vEthernet (dockerExternalSwitch)" -AddressFamily "IPv4" | select -expand          IPAddress
 
debug-output "IPv4: $($IPv4)"
 $env:DISPLAY=$IPv4 + ":0.0"

if (! $local) 
  #set up to use docker-machine using docker-machine env dev1


docker run -ti --name devworkstation --rm --net=host -v /var/run/docker.sock:/var/run/docker.sock -e DISPLAY=$env:DISPLAY    xxx/xxx:devworkstation

现在 x11 转发可以与 docker-machine 一起使用,并且不带 docker-machine。

【讨论】:

以上是关于当图像在 docker 机器中运行时,X11 转发不起作用,但如果图像在没有 docker 机器的情况下运行,则它可以正常工作的主要内容,如果未能解决你的问题,请参考以下文章

当 Java APM 代理在 Docker 中运行时,如何将 Java APM 代理连接到 APM 服务器?

为啥我的图像出现在 Android Studio 设计视图中,但在手机中运行时却没有?

在 docker 容器中运行时找不到 curl 命令

当应用程序在本地运行时,Node.js 能够连接到 MySQL 容器,但当应用程序在容器中运行时无法连接

X11 MATLAB 显示图

在 Docker 中运行时,`npm install` 导致`cb() never called!`