web-dev-qa-db-ja.com

GUIベースの環境用のDocker?

問題

エンタープライズWebアプリケーションの一部であるクライアントマシンのセットがあります。各マシンは、サーバーに接続するPyQTベースのWebクライアントである同一のソフトウェアを実行します。このクライアントソフトウェアは定期的に更新されます。各マシンで同じ環境を使用できるようにする構成/プロビジョニングツールがあり、クライアントの各マシンにソフトウェアを簡単に展開および構成できます。

問題は、私がChefを使用しようとしたことですが、実際にChefの知識とスキルを維持するには多大な労力が必要であり(専用のOps担当者はいません)、さらにサードパーティのリポジトリがあるとChefレシピが失敗する可能性があります もう利用できません (これは主要なストッパーです)。

この問題を解決するためにDockerを試してみたいと思いますが、GUIベースのソフトウェアが動作できるようにするイメージ/コンテナーをセットアップできる場合は、私は まだわかりません を使用します。

質問

Dockerを使用して、GUIベースのアプリケーション(PyQt/QT)の開発/運用環境を構築することは可能ですか?はいの場合、それにアプローチする最初のステップは何ですか?

34
skanatek

現在、この質問には回答されていませんが、Googleで非常に高い評価を得ています。他の答えはほとんど正しいですが、難しい方法を学んだといういくつかの注意事項があり、他の人のトラブルを救いたいと思います。

Nasser Alshammariの答えは、Dockerコンテナー内でGTKアプリケーションを実行するための最も簡単な(そして最も速い)アプローチです-XサーバーのソケットをDockerボリュームとしてマウントし、代わりにDockerに使用するように指示します。

docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY TheImage

(X11アプリケーションをルートとして実行することは常に機能しないため、-u <username-within-container>フラグを渡すことをお勧めします。通常はお勧めしません。セッションを共有する場合は特にをお勧めします)。

これは、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

「おそらく」と言うのは、このアプローチを十分なQtアプリケーションでテストしていないか、Qtソースコードを掘り下げて、なぜこれがサポートされないのかを理解していないからです。 YMMV、そしてあなたは幸運になるかもしれませんが、Dockerコンテナ内からQtベースのアプリケーションを実行しようとしている場合、「昔ながらの」アプローチとeither

  1. コンテナ内でsshdを実行し、X11転送をオンにしてから、ssh -X(より安全)またはssh -Y(安全性が低い、使用済みonlyを使用してコンテナに接続しますコンテナ化されたアプリケーション)。

  2. コンテナ内でVNCを実行し、ホストからVNCクライアントで接続します。

これらの2つのオプションのうち、最初のオプションをお勧めしますが、どちらが最適かを確認してください。

21
chimeracoder

DockerコンテナでGUIアプリを実行するには、多くのソリューションがあります。たとえば、SSHまたはVNCを使用できます。ただし、オーバーヘッドと遅延が追加されます。私が見つけた最良の方法は、ホストマシンのXサーバーが使用するファイルをボリュームとしてコンテナに渡すことです。このような:

docker run -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY TheImage

その後、すべてのGUIアプリがコンテナーから実行されます。

お役に立てれば!

9

コンテナでxeyesを実行し、コンテナの外部で実行されているXサーバーの「ウィンドウ」を確認しました。方法は次のとおりです。

Xephyrを使用して、ネストされたXサーバーを実行しました。これは必須ではありませんが、ほとんどのLinuxデスクトップではデフォルトでリモートアプリの実行が許可されていません( here がubuntuでこれを「修正」する方法)。

Xephyrをインストールします。

$ Sudo apt-get install xserver-xephyr

Xephyrを実行します。

$ Xephyr -ac -br -noreset -screen 800x600 -Host-cursor :1

これにより、Xサーバーとして機能する新しい800x600ウィンドウが作成されます。

マシンの「外部」アドレスを見つけます。 Xサーバーが実行されている場所は次のとおりです。

$ ifconfig

docker0   Link encap:Ethernet  HWaddr 56:84:7a:fe:97:99  
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::5484:7aff:fefe:9799/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:133395 errors:0 dropped:0 overruns:0 frame:0
          TX packets:242570 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:9566682 (9.5 MB)  TX bytes:353001178 (353.0 MB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:650493 errors:0 dropped:0 overruns:0 frame:0
          TX packets:650493 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2506560450 (2.5 GB)  TX bytes:2506560450 (2.5 GB)

wlan0     Link encap:Ethernet  HWaddr c4:85:08:97:b6:de  
          inet addr:192.168.129.159  Bcast:192.168.129.255  Mask:255.255.255.0
          inet6 addr: fe80::c685:8ff:fe97:b6de/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6587370 errors:0 dropped:1 overruns:0 frame:0
          TX packets:3716257 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:7405648745 (7.4 GB)  TX bytes:693693327 (693.6 MB)

127.0.0.1は使用しないでください!他のどれでも使用できます。 172.17.42.1を使用します。

次のコンテンツでDockerfileを作成します。

FROM ubuntu

RUN apt-get update
RUN apt-get install -y x11-apps

CMD ["/usr/bin/xeyes"]

ビルドする:

$ docker build -t xeyes .

そしてそれを実行します:

$ docker run -e DISPLAY=172.17.42.1:1.0 xeyes

DISPLAY環境変数を表示したい場所に設定していることに注意してください。

同じ手法を使用して、表示を任意のXサーバーにリダイレクトできます。

4
ivant

最近、ドッカーでPyQt5アプリケーションを実行しようとしました。私が学んだことは、アプリケーションをルートとして実行できないことです(通常のユーザーを作成する必要があります)。アプリケーションでオーディオ/ビデオを再生するには、グループ「audio」でdocker containerを実行し、サウンドデバイスをマウントする必要があります。私のアプリケーションを実行するには、これを使用します:

docker run -it \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -v $(pwd)/test:/app \
    -e DISPLAY=$DISPLAY \
    -u myusername \
    --group-add audio \
    --device /dev/snd \
    fadawar/docker-pyqt5-qml-qtmultimedia python3 /app/hello.py

コンテナーに追加してPyQtアプリケーションを実行する必要があるパッケージを特定するまでしばらく時間がかかるので、他のユーザーが簡単に使用できるように、いくつかのDockerfiles(簡単なデモアプリ)を作成しました。

Python 3 + PyQt5: https://github.com/jozo/docker-pyqt5

Python 3 + PyQt5 + QML + QtMultimedia: https://github.com/jozo/docker-pyqt5-qml-qtmultimedia

1
jozo

subuser を使用して、GUIアプリケーションをパッケージ化できます。また、アプリケーションの更新を適切にサポートしています。 Dockerfilesをgitリポジトリに1回入れてから、subuser update all各クライアントで、変更が必要なときにイメージを再構築します。

1
timthelion

順調に動作させるために必要な基本手順は次のとおりです。

  1. Dockerコンテナーを作成して実行するには

    Sudo nvidia-docker run -it -d --privileged -e DISPLAY=$DISPLAY --name wakemeeup -v -v /dev:/dev -v /tmp/.X11-unix:/tmp/.X11-unix:rw nvidia/cuda:9.1-cudnn7-devel-ubuntu16.04 bash

  2. Dockerコンテナを開始するには

    Sudo docker start wakemeup

  3. Dockerコンテナに接続するには

    xhost +local:root 1>/dev/null 2>&1 docker exec -u $USER -it wakemeup /bin/bash xhost -local:root 1>/dev/null 2>&1

  4. MIT-SHMはXサーバーの拡張機能であり、共有メモリを使用することでトランザクションを高速化できます。 Docker分離はおそらくそれをブロックします。 Qtアプリケーションは、拡張機能を使用しないように強制できます。 Dockerコンテナ内で、

    nano ~/.bashrc export QT_X11_NO_MITSHM=1

  5. ソース.bashrc

    source ~/.bashrc

これが役立つことを願っています

1
GPrathap

解決済み-DockerコンテナのPyQt5-GUI:

Qt-Debugを有効にする_$ export QT_DEBUG_PLUGINS=1_ ==>エラーを再現する==>デバッグメッセージにリストされている_No such file or directory_- libraryを再インストールします==>繰り返します!

また、エラーを受信せずにDockerコンテナーでPyQt5-GUI-appを実行することもできませんでした。まず、DockerコンテナーでQtを実行できないというすべての投稿を読みました。しかし、私はそれを解決できました(少なくとも私にとって)...

システム

私はDockerコンテナ内のPyQt5-applicationを共有_/tmp/.X11-unix/_ソケットとGUI視覚化のためのディスプレイで実行しています:

_$ nividia-docker run --interactive --tty --env DISPLAY=$DISPLAY --volume /tmp/.X11-unix/:/tmp/.X11-unix/ <docker_iamge>
_

エラー

_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)
_

PyCharmデバッグモードでは、エラーが返されました。

_Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
_

解決

一般的な方法:

  • dockerコンテナターミナルでQt-debug環境変数を設定します。
_   $ export QT_DEBUG_PLUGINS=1
_
  • dockerターミナル(またはIDE)でエラーを再現します。例:
_$ 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([])
_
  • 端末に出力されるデバッグメッセージを読み取ります。例:
_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)
_
  • ここで_<No such file or directory>.so.*_および_<coud not be loaded>_--パッケージを見つけます。 _libxkbcommon-x11.so.0_およびlibxcb。次に、対応するパッケージ/ライブラリを再/インストールします(パッケージの検索は_apt-file --package-only search <filename>_または_conda/pip search ..._で機能します)。私の場合、次のライブラリが必要でした:
_### lib no.1 ###
$ Sudo conda install --name <env_name> --force-reinstall libxcb    # or pip install ...
### lib no. 2 ###
$ apt-file --package-only search libxkbcommon-x11.so.0
libxkbcommon-x11-0
$ Sudo apt install libxkbcommon-x11-0 
_

順次再生されるすべてのデバッグメッセージに対してこのプロセスを繰り返し、2つのライブラリをインストールした後、ローカルマシンのデスクトップのDockerコンテナー内からPyQt5-appsを実行できるようになりました。

0
drstoop