Docker pour les environnements GUI?

Problème

j'ai un ensemble de machines clientes qui font partie d'une application web d'entreprise. Chaque machine exécute le même logiciel, qui est un client Web basé sur PyQT qui se connecte à un serveur. Ce logiciel client est mis à jour régulièrement et j'aimerais avoir un outil de configuration/fourniture qui permette d'avoir le même environnement sur chaque machine et donc de fournir un déploiement et une configuration faciles du logiciel sur chacun des clients machine.

le problème est que j'ai essayé D'utiliser Chef, mais il faut beaucoup d'effort pour réellement maintenir les connaissances et les compétences de Chef (nous n'avons pas un gars dédié aux opérations) et en outre une recette de Chef peut échouer si un dépôt tiers n'est plus disponible (c'est un bouchon principal).

je voudrais essayer de Docker pour résoudre le problème, mais je ne sais pas s'il est possible de configurer des images / conteneurs qui permettent une certaine interface graphique basé sur le logiciel à utiliser.

Question

est-il possible d'utiliser Docker pour avoir un environnement de développement/production pour une application basée sur GUI (PyQt/QT)? Si oui, quelles en seraient les premières étapes de la démarche?

26
demandé sur skanatek 2014-06-07 13:53:33

5 réponses

actuellement cette question n'est pas répondue, mais elle est très bien classée sur Google. Les autres réponses sont généralement correctes, mais avec quelques mises en garde que j'ai appris à la dure, et je voudrais sauver d'autres problèmes.

la réponse donnée par Nasser Alshammari est l'approche la plus simple (et la plus rapide) pour exécuter des applications GTK à l'intérieur d'un conteneur Docker - montez simplement la socket pour le serveur X comme un volume Docker et dites à Docker d'utiliser cela plutôt.

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

(je voudrais également vous recommandons de passer l' -u <username-within-container> flag, comme lancer des applications X11 en tant que root ne fonctionne pas toujours, et n'est généralement pas recommandé, surtout lors de sessions de partage).

cela fonctionnera pour les applications telles que xterm, ainsi que des applications basées sur GTK. Par exemple, si vous essayez cela avec Firefox (qui est basé sur GTK), cela fonctionnera (notez que si vous exécutez déjà Firefox sur l'hôte, cela ouvrira une nouvelle fenêtre dans l'hôte plutôt que d'ouvrir une nouvelle instance de Firefox à partir de l'intérieur du conteneur).

cependant, votre réponse pose des questions sur PyQT en particulier. il s'avère que Qt ne supporte pas le partage de x sessions de cette façon (ou au moins ne le supporte pas bien).

si vous essayez d'exécuter une application basée sur QT de cette façon, vous obtiendrez probablement une erreur comme celle-ci:

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

je dis "probablement" parce que je n'ai pas testé approche avec suffisamment d'applications Qt pour être sûr, ou creusé dans le code source Qt assez pour comprendre pourquoi cela n'est pas supporté. YMMV, et vous pouvez obtenir de la chance, mais si vous cherchez à exécuter une application basée sur Qt à partir de l'intérieur d'un conteneur Docker, vous pouvez avoir à aller l'approche "old-fashioned" et

  1. Lancez sshd dans le conteneur, activez X11 forwarding, puis connectez - vous au conteneur en utilisant ssh -X (plus sécurisé) ou ssh -Y (moins sûr, utilisé si vous faites entièrement confiance à l'application containerized).

  2. exécutez VNC dans le conteneur, et connectez-le depuis l'hôte avec un client VNC.

entre ces deux options, je recommande la première, mais voir ce qui fonctionne le mieux pour votre situation.

16
répondu chimeracoder 2016-08-08 20:37:16

Il existe de nombreuses solutions pour avoir des applications GUI fonctionnant dans un conteneur docker. Vous pouvez utiliser SSH, ou VNC par exemple. Mais ils ajoutent des coûts et des délais. La meilleure façon que j'ai trouvée est juste de passer dans le fichier utilisé par le serveur X dans la machine hôte comme un volume au conteneur. Comme ceci:

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

alors toutes vos applications graphiques fonctionneront à partir du conteneur.

espérons que cela aide!

8
répondu nasser alshammari 2014-10-07 15:18:57

j'ai réussi à exécuter xeyes dans un récipient et voir la "fenêtre" dans un serveur X à l'extérieur du conteneur. Voici comment faire:

j'ai utilisé Xephyr pour exécuter un serveur X imbriqué. Ce n'est pas nécessaire, mais la plupart des ordinateurs de bureau linux ne permettent pas d'exécuter des applications distantes sur eux par défaut (ici's comment "réparer" cela sur ubuntu).

Installer Xephyr:

$ sudo apt-get install xserver-xephyr

Exécuter Xephyr:

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

cela crée une nouvelle fenêtre 800x600, qui agit comme un X serveur.

trouver une adresse "externe" de votre machine. C'est ici que le serveur X tourne:

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

N'utilisez pas 127.0.0.1! Vous pouvez utiliser l'une des autres. Je vais utiliser 172.17.42.1.

Créer un Dockerfile avec le contenu suivant:

FROM ubuntu

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

CMD ["/usr/bin/xeyes"]

Construire:

$ docker build -t xeyes .

Et l'exécuter:

$ docker run -e DISPLAY=172.17.42.1:1.0 xeyes

notez que je mets la variable D'environnement DISPLAY à l'endroit où je veux la voir.

Vous pouvez utiliser le même technique pour rediriger l'affichage vers n'importe quel serveur X.

3
répondu ivant 2017-04-13 12:22:42

Vous pouvez utiliser utilisateur normal pour empaqueter vos applications GUI. Il a également un bon soutien pour la mise à jour des applications. Vous pouvez mettre vos fichiers Dockerfiles dans un git repo une fois, et puis juste courir subuser update all sur chaque client pour reconstruire les images quand elles doivent être changées.

1
répondu timthelion 2014-10-16 11:54:45

récemment j'ai essayé D'exécuter L'application PyQt5 dans docker. Ce que j'ai appris, c'est que vous ne pouvez pas exécuter application en tant que root (vous devez créer un utilisateur normal). Lorsque vous voulez lire l'audio/vidéo dans l'application, vous devez exécuter Docker conteneur avec le groupe "audio" et monter le périphérique sonore. Donc, pour exécuter mon application j'utilise ceci:

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

je passe un certain temps jusqu'à ce que je trouve quels paquets j'ai besoin d'ajouter à mon conteneur pour exécuter L'application PyQt dedans donc j'ai créé quelques fichiers Dockerfiles (avec simple demo app) pour le rendre plus facile pour les autres:

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

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

1
répondu fadawar 2016-08-08 20:19:22