
Error: GDK_BACKEND does not match available displays
我的第一个想法是实际将$DISPLAY传递给容器,其中包含“-e”选项,如下所示:
docker run -ti -e DISPLAY=$DISPLAY name_of_docker_image
这有帮助,但它没有解决问题.错误消息更改为:
Unable to init server: Broadway display type not supported: localhost:10.0
Error: cannot open display: localhost:10.0
在搜索网络后,我发现我可以做一些xauth魔术来修复身份验证.我添加了以下内容:
SOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
chmod 777 $XAUTH
docker run -ti -e DISPLAY=$DISPLAY -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH \
-e XAUTHORITY=$XAUTH name_of_docker_image
但是,这仅在将“–net host”添加到docker命令时才有效:
docker run -ti -e DISPLAY=$DISPLAY -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH \
-e XAUTHORITY=$XAUTH --net host name_of_docker_image
这是不可取的,因为它使整个主机网络对容器可见.
为了让它完全在没有“–net host”的docker中的远程服务器上运行,现在缺少什么?
任何X应用程序都使用$DISPLAY中的主机名,通常是“localhost”并使用TCP连接.然后将其隧道传送回SSH客户端.当Docker使用“–net host”时,Docker容器的“localhost”与Docker主机相同,因此它可以正常工作.
如果未指定“–net host”,则Docker将使用默认的网桥模式.这意味着“localhost”意味着容器内部的其他内容与主机相同,容器内的X应用程序将无法通过引用“localhost”来查看X服务器.因此,为了解决这个问题,必须将“localhost”替换为主机的实际IP地址.这通常是“172.17.0.1”或类似的.检查“docker0”接口的“ip addr”.
这可以通过sed替换来完成:
DISPLAY=`echo $DISPLAY | sed 's/^[^:]*\(.*\)/172.17.0.1\1/'`
此外,SSH服务器通常未配置为接受与此X11隧道的远程连接.然后必须通过编辑/ etc / ssh / sshd_config(至少在Debian中)并设置来更改它:
X11UseLocalhost no
然后重新启动SSH服务器,并使用“ssh -X”重新登录服务器.
这几乎是这样,但还有一个复杂因素.如果Docker主机上正在运行任何防火墙,则必须打开与X11隧道关联的TCP端口.端口号是:和之间的数字.在$DISPLAY中添加到6000.
要获取TCP端口号,您可以运行:
X11PORT=`echo $DISPLAY | sed 's/^[^:]*:\([^\.]\+\).*/\1/'`
TCPPORT=`expr 6000 + $X11PORT`
然后(如果使用ufw作为防火墙),为172.17.0.0子网中的Docker容器打开此端口:
ufw allow from 172.17.0.0/16 to any port $TCPPORT proto tcp
所有命令可以放在一个脚本中:
XAUTH=/tmp/.docker.xauth
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | sudo xauth -f $XAUTH nmerge -
sudo chmod 777 $XAUTH
X11PORT=`echo $DISPLAY | sed 's/^[^:]*:\([^\.]\+\).*/\1/'`
TCPPORT=`expr 6000 + $X11PORT`
sudo ufw allow from 172.17.0.0/16 to any port $TCPPORT proto tcp
DISPLAY=`echo $DISPLAY | sed 's/^[^:]*\(.*\)/172.17.0.1\1/'`
sudo docker run -ti --rm -e DISPLAY=$DISPLAY -v $XAUTH:$XAUTH \
-e XAUTHORITY=$XAUTH name_of_docker_image
假设你不是root用户,因此需要使用sudo.
而不是sudo chmod 777 $XAUTH,你可以运行:
sudo chown my_docker_container_user $XAUTH
sudo chmod 600 $XAUTH
防止服务器上的其他用户如果知道您为/tmp/.docker.auth文件创建了什么,也能够访问X服务器.
我希望这可以使它适用于大多数情况.
转载注明原文:在没有“–net host”的SSH连接的服务器上可靠地在Docker容器中运行X应用程序 - 乐贴网