我有一个基于Qt5的C++ GUI,我希望能够从Docker容器内运行它。
当我尝试使用以下命令启动时:
docker run --rm -it my_image
这将导致错误输出。
qt.qpa.xcb: could not connect to display localhost:10.0
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, xcb.
因此,我搜索了如何做到这一点。我找到了在Docker容器中使用GUI Qt应用程序的文章,并基于此使用以下命令进行调用:
QT_GRAPHICSSYSTEM="native" docker run -it -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix my_image
这导致出现了相同的错误。
然后我发现了在Docker容器中是否可以运行GUI应用程序?。
那里被接受的答案似乎只适用于某些应用程序,例如Firefox?
向下滚动,我得到了一个解决方案,告诉我在sshd_config
中设置X11UseLocalhost no
,然后像这样调用:
docker run -v $HOME:/hosthome:ro -e XAUTHORITY=/hosthome/.Xauthority -e DISPLAY=$(echo $DISPLAY | sed "s/^.*:/$(hostname -i):/") my_image
这会产生与上面错误略有不同的变化:
qt.qpa.xcb: could not connect to display 127.0.1.1:13.0
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
Available platform plugins are: eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, xcb.
在参考另一个答案后,我在我的Dockerfile中添加了ENV DISPLAY :0
并使用以下方式调用它
xhost +
XSOCK=/tmp/.X11-unix/X0
docker run -v $XSOCK:$XSOCK my_image
这次,我的错误信息第一行是qt.qpa.xcb: could not connect to display :0
。
然后我尝试了另一个答案,添加了:
RUN export uid=0 gid=0 && \
mkdir -p /home/developer && \
echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
echo "developer:x:${uid}:" >> /etc/group && \
mkdir /etc/sudoers.d/ && \
echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
chmod 0440 /etc/sudoers.d/developer && \
chown ${uid}:${gid} -R /home/developer
我将以下内容添加到我的Dockerfile中,并运行了docker run -ti --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix my_image
,但还是遇到了相同的错误。
我也尝试了http://wiki.ros.org/docker/Tutorials/GUI中描述的几种方法,但仍然出现了相同的错误。
我哪里做错了吗?请注意,我通过SSH在远程机器上工作,并打开了X11转发(应用程序在Docker之外正常运行)。还请注意,我编写的是一个客户端-服务器应用程序,服务器部分不需要GUI元素,但大部分源代码都可以从其容器中正常运行。
我希望找到一种解决方案,无需更改系统,因为我使用Docker的原因就是为了让我的应用程序用户能够轻松地运行它。
xhost +
- eyllanescxhost +
禁用 X 服务器的访问控制,因此任何人(即使是通过网络连接)都有权限访问它(并在您的屏幕上显示内容或捕获您的按键等)。 我学习时被告知永远不要做这样的事情。 - David Mazexhost +si:localuser:$USER
即可。我想这对我来说不相关,但在这个背景下还是想提一下。 - Aziuth