基于GUI的环境的Docker?

ska*_*tek 37 qt configuration-management chef-infra vagrant docker

问题

我有一组客户机,它们是企业Web应用程序的一部分.每台机器运行相同的软件,这是一个连接到服务器的基于PyQT的Web客户端.这个客户端软件定期更新,我希望有一些配置/配置工具,允许在每台机器上拥有相同的环境,从而在每个客户机器上轻松部署和配置软件.

问题是我尝试使用Chef,但实际维护Chef知识和技能需要付出很多努力(我们没有专门的Ops人),而且如果某个第三方存储库不再存在,则Chef配方可能会失败可用(这是一个主要的塞子).

我想尝试使用Docker解决问题,但我仍然不知道是否可以设置允许某些基于GUI的软件运行的图像/容器.

是否可以使用Docker为基于GUI的应用程序(PyQt/QT)提供开发/生产环境?如果是的话,接下来的第一步是什么?

chi*_*der 23

目前这个问题没有得到解答,但在Google上排名很高.其他答案大多是正确的,但有一些警告,我已经学到了很多困难,我想拯救别人的麻烦.

Nasser Alshammari给出的答案是在Docker容器中运行GTK应用程序的最简单(也是最快)的方法 - 只需将X服务器的套接字挂载为Docker卷,并告诉Docker使用它.

docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY TheImage
Run Code Online (Sandbox Code Playgroud)

(我还建议传递-u <username-within-container>标志,因为以root身份运行X11应用程序并不总是有效,通常不建议使用,特别是在共享会话时).

这适用于诸如xterm基于GTK的应用程序之类的应用程序.例如,如果您使用Firefox(基于GTK)尝试此操作,它将起作用(请注意,如果您已经在主机上运行Firefox,它将在主机中打开一个新窗口而不是打开一个新的Firefox实例从容器内).

但是,您的答案特别询问了PyQT.事实证明,Qt不支持以这种方式共享X会话(或者至少不支持它).

如果您尝试以这种方式运行基于QT的应用程序,您可能会收到如下错误:

X Error: BadAccess (attempt to access private resource denied) 10
  Extension:    140 (MIT-SHM)
  Minor opcode: 1 (X_ShmAttach)
  Resource id:  0x12d
X Error: BadShmSeg (invalid shared segment parameter) 148
  Extension:    140 (MIT-SHM)
  Minor opcode: 5 (X_ShmCreatePixmap)
  Resource id:  0xb1
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
  Major opcode: 62 (X_CopyArea)
  Resource id:  0x2c0000d
X Error: BadDrawable (invalid Pixmap or Window parameter) 9
  Major opcode: 62 (X_CopyArea)
  Resource id:  0x2c0000d
Run Code Online (Sandbox Code Playgroud)

我说"可能"是因为我没有用足够的Qt应用程序来测试这种方法,或者深入研究Qt源代码,足以弄清楚为什么不支持它.YMMV,你可能会很幸运,但如果你想在Docker容器中运行一个基于Qt的应用程序,你可能不得不采用"老式"方法,要么

  1. 在容器中运行sshd,打开X11转发,然后使用ssh -X(更安全)或ssh -Y(安全性较低,在完全信任容器化应用程序时使用)连接到容器.

  2. 在容器中运行VNC,并使用VNC客户端从主机连接到VNC.

在这两个选项之间,我会推荐第一个,但看看哪个最适合你的情况.

  • _export QT_X11_NO_MITSHM = 1_将修复您的QT错误. (11认同)
  • 明白,但我想专门记录 Qt 的行为,因为它是 OP 问题的关键部分。如果其他人在调试时偶然发现此页面(就像我今天早些时候所做的那样!),我只是想确保他们不必重复这项工作。:) (3认同)
  • 如果出现错误“Gtk-WARNING:无法打开显示:unix:0.0”,请尝试以下操作:xhost +local:docker https://hub.docker.com/r/meertec/firefox/ (2认同)

小智 11

有许多解决方案可以在docker容器中运行GUI应用程序.例如,您可以使用SSH或VNC.但他们增加了一些开销和延迟.我找到的最好的方法就是将主机中X服务器使用的文件作为卷传递给容器.像这样:

docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY TheImage
Run Code Online (Sandbox Code Playgroud)

然后,所有GUI应用程序都将从容器运行.

希望这可以帮助!


drs*_*oop 5

已解决 - Docker 容器中的 PyQt5-GUI:

启用 Qt-Debug $ export QT_DEBUG_PLUGINS=1 ==> 重现错误 ==> 重新/安装No such file or directory调试消息中列出的库 ==> 重复!

我也无法在 Docker 容器中运行 PyQt5-GUI-app 而不会收到错误,并且首先阅读了所有关于无法在 Docker 容器中运行 Qt 的帖子。但我可以解决它(至少对我来说)......

系统

我正在Docker 容器中运行PyQt5 应用程序,该容器具有共享/tmp/.X11-unix/套接字并显示 GUI 可视化:

$ nividia-docker run --interactive --tty --env DISPLAY=$DISPLAY --volume /tmp/.X11-unix/:/tmp/.X11-unix/ <docker_iamge>
Run Code Online (Sandbox Code Playgroud)

错误

初始化PyQt5.QtWidgets.QApplication总是导致以下错误:

Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt5.QtWidgets import QApplication
>>> app = QApplication([])
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, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl, xcb.

Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

在 PyCharm 调试模式下返回错误:

Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
Run Code Online (Sandbox Code Playgroud)

解决方案

一般方法:

  • 在docker容器终端中设置Qt-debug环境变量:
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
Run Code Online (Sandbox Code Playgroud)
  • 在 docker 终端(或 IDE)中重现错误,例如:
   $ export QT_DEBUG_PLUGINS=1
Run Code Online (Sandbox Code Playgroud)
  • 读取打印到终端的调试消息,例如:
QFactoryLoader::QFactoryLoader() checking directory path "/conda/envs/rapids/lib/python3.6/site-packages/PyQt5/Qt/plugins/platforms" ...
QFactoryLoader::QFactoryLoader() looking at "/conda/envs/rapids/lib/python3.6/site-packages/PyQt5/Qt/plugins/platforms/libqeglfs.so"
Found metadata in lib /conda/envs/rapids/lib/python3.6/site-packages/PyQt5/Qt/plugins/platforms/libqeglfs.so, metadata=
{
    "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3",
    "MetaData": {
        "Keys": [
            "eglfs"
        ]
    },
...
...
...
Got keys from plugin meta data ("xcb")
QFactoryLoader::QFactoryLoader() checking directory path "/conda/envs/rapids/bin/platforms" ...
Cannot load library /conda/envs/rapids/lib/python3.6/site-packages/PyQt5/Qt/plugins/platforms/libqxcb.so: (libxkbcommon-x11.so.0: cannot open shared object file: No such file or directory)
QLibraryPrivate::loadPlugin failed on "/conda/envs/rapids/lib/python3.6/site-packages/PyQt5/Qt/plugins/platforms/libqxcb.so" : "Cannot load library /conda/envs/rapids/lib/python3.6/site-packages/PyQt5/Qt/plugins/platforms/libqxcb.so: (libxkbcommon-x11.so.0: cannot open shared object file: No such file or directory)"
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, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl, xcb.

Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
  • 找到<No such file or directory>.so.*and <coud not be loaded>-packages,这里例如libxkbcommon-x11.so.0and libxcbapt-file --package-only search <filename>然后重新/安装相应的包/库(使用或查找包conda/pip search ...)。就我而言,需要以下库:
$ python
Python 3.6.8 |Anaconda, Inc.| (default, Dec 30 2018, 01:22:34) 
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> 
KeyboardInterrupt
>>> from PyQt5.QtWidgets import QApplication, QLabel
>>> app = QApplication([])
Run Code Online (Sandbox Code Playgroud)

对所有按顺序重现的调试消息重复此过程并安装 2 个库后,我现在可以从本地计算机桌面上的 Docker 容器内部运行 PyQt5-apps。