tag run remove hub example compose qt vagrant chef docker configuration-management

qt - run - docker tag example



Docker para entornos basados en GUI (5)

Problema

Tengo un conjunto de máquinas cliente que son parte de una aplicación web empresarial. Cada máquina ejecuta un software idéntico, que es un cliente web basado en PyQT que se conecta a un servidor. Este software de cliente se actualiza regularmente y me gustaría tener alguna herramienta de configuración / aprovisionamiento que permita tener el mismo entorno en cada máquina y, por lo tanto, proporcionar una implementación y configuración fáciles del software en cada una de las máquinas de los clientes.

El problema es que he tratado de usar Chef, pero se necesita un gran esfuerzo para mantener el conocimiento y las habilidades del Chef (no tenemos un tipo dedicado de Ops) y, además, una receta Chef puede fallar si algún repositorio de terceros ya no es disponible (este es un tapón principal).

Me gustaría probar Docker para resolver el problema, pero todavía no sé si es posible configurar imágenes / contenedores que permitan que funcione algún software basado en GUI.

Pregunta

¿Es posible usar Docker para tener un entorno de desarrollo / producción para una aplicación basada en GUI (PyQt / QT)? En caso afirmativo, ¿cuáles serían los primeros pasos para abordar eso?


Actualmente esta pregunta no recibe respuesta, pero está muy bien clasificada en Google. Las otras respuestas son en su mayoría correctas, pero con algunas advertencias que he aprendido de la manera difícil, y me gustaría salvar a otros problemas.

La respuesta dada por Nasser Alshammari es el enfoque más simple (y más rápido) para ejecutar aplicaciones GTK dentro de un contenedor Docker: simplemente monte el zócalo para el servidor X como un volumen Docker y diga a Docker que lo use en su lugar.

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

(También recomendaría pasar el indicador -u <username-within-container> , ya que ejecutar aplicaciones X11 como root no siempre funciona, y generalmente no se recomienda, especialmente cuando se comparten sesiones).

Esto funcionará para aplicaciones como xterm , así como para aplicaciones basadas en GTK. Por ejemplo, si prueba esto con Firefox (que está basado en GTK), funcionará (tenga en cuenta que si ya está ejecutando Firefox en el host, se abrirá una nueva ventana en el host en lugar de abrir una nueva instancia de Firefox desde dentro del contenedor).

Sin embargo , su respuesta pregunta específicamente sobre PyQT. Resulta que Qt no admite compartir sesiones X de esta manera (o al menos no lo admite bien).

Si intenta ejecutar una aplicación basada en QT de esta manera, probablemente obtendrá un error como el siguiente:

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

Digo "probablemente" porque no he probado este enfoque con suficientes aplicaciones de Qt para estar seguro, o busqué en el código fuente de Qt lo suficiente para descubrir por qué esto no es compatible. YMMV, y puede tener suerte, pero si está buscando ejecutar una aplicación basada en Qt desde un contenedor Docker, es posible que tenga que adoptar el enfoque "anticuado" y

  1. Ejecute sshd dentro del contenedor, active el reenvío X11 y luego conéctese al contenedor utilizando ssh -X (más seguro) o ssh -Y (menos seguro, se usa solo si confía plenamente en la aplicación en contenedor).

  2. Ejecute VNC dentro del contenedor y conéctese desde el host con un cliente VNC.

Entre esas dos opciones, recomendaría la primera, pero vea cuál funciona mejor para su situación.


Hay muchas soluciones para ejecutar aplicaciones GUI en un contenedor acoplable. Puede usar SSH o VNC, por ejemplo. Pero agregan algo de sobrecarga y retraso. La mejor forma que encontré es simplemente pasar el archivo utilizado por el servidor X en la máquina host como un volumen para el contenedor. Me gusta esto:

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

Entonces todas sus aplicaciones GUI se ejecutarán desde el contenedor.

¡Espero que esto ayude!


Logré ejecutar xeyes en un contenedor y ver la "ventana" en un servidor X ejecutándose fuera del contenedor. Así es cómo:

Usé Xephyr para ejecutar un Servidor X anidado. Esto no es necesario, pero la mayoría de los escritorios Linux no permiten ejecutar aplicaciones remotas en ellos de manera predeterminada ( here explica cómo "arreglar" esto en Ubuntu).

Instalar Xephyr:

$ sudo apt-get install xserver-xephyr

Ejecutar Xephyr:

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

Esto crea una nueva ventana de 800x600, que actúa como un servidor X.

Encuentre una dirección "externa" de su máquina. Aquí es donde se ejecuta el servidor 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)

No use 127.0.0.1! Puedes usar cualquiera de los otros. Usaré 172.17.42.1.

Crea un Dockerfile con el siguiente contenido:

FROM ubuntu RUN apt-get update RUN apt-get install -y x11-apps CMD ["/usr/bin/xeyes"]

Constrúyelo:

$ docker build -t xeyes .

Y ejecutarlo:

$ docker run -e DISPLAY=172.17.42.1:1.0 xeyes

Tenga en cuenta que estoy configurando la variable de entorno DISPLAY en el lugar donde quiero verla.

Puede usar la misma técnica para redirigir la pantalla a cualquier servidor X.


Puede usar el subuser para empaquetar sus aplicaciones GUI. También tiene un buen soporte para la actualización de aplicaciones. Puede colocar sus archivos Docker en un repositorio git una vez, y luego ejecutar la subuser update all en cada cliente para reconstruir las imágenes cuando es necesario cambiarlas.


Recientemente traté de ejecutar la aplicación PyQt5 en el acoplador. Lo que aprendí es que no puedes ejecutar la aplicación como root (tienes que crear un usuario normal). Cuando desee reproducir audio / video en la aplicación, debe ejecutar el contenedor acoplable con el grupo "audio" y montar el dispositivo de sonido. Entonces, para ejecutar mi aplicación, uso esto:

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

Pasé algún tiempo hasta que descubrí qué paquetes necesito agregar a mi contenedor para ejecutar la aplicación PyQt, así que creé algunos Dockerfiles (con una aplicación de demostración sencilla) para que otros puedan hacerlo más fácilmente:

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

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