Docker dla środowisk opartych na GUI?

Problem

Mam zestaw maszyn klienckich, które są częścią korporacyjnej aplikacji internetowej. Każda maszyna uruchamia identyczne oprogramowanie, które jest klientem internetowym opartym na PyQT, który łączy się z serwerem. To oprogramowanie klienckie jest regularnie aktualizowane i chciałbym mieć jakieś narzędzie do konfiguracji/aprowizacji, które pozwala mieć to samo środowisko na każdej maszynie, a tym samym zapewnić łatwe wdrożenie i konfigurację oprogramowania na każdej maszynie klienta.

The problem polega na tym, że próbowałem użyć Chef, ale to wymaga dużo wysiłku, aby faktycznie utrzymać wiedzę i umiejętności szefa kuchni (nie mamy dedykowanego faceta Ops), a ponadto przepis Szefa Kuchni może zawieść, jeśli jakieś zewnętrzne repozytorium nie jest już dostępne (jest to główny korek).

Chciałbym spróbować Docker rozwiązać problem, ale nadal Nie wiem czy jest możliwe skonfigurowanie obrazów / kontenerów, które pozwalają na niektóre oprogramowanie oparte na GUI do operuj.

Pytanie

Czy możliwe jest użycie Dockera, aby mieć środowisko programistyczne/produkcyjne dla aplikacji opartej na GUI (PyQt/QT)? Jeśli tak, to jakie byłyby pierwsze kroki, aby się do tego zbliżyć?

Author: skanatek, 2014-06-07

5 answers

Obecnie na to pytanie nie ma odpowiedzi, ale jest bardzo wysoko w rankingu Google. Pozostałe odpowiedzi są w większości poprawne, ale z pewnymi zastrzeżeniami, że nauczyłem się na własnej skórze i chciałbym zaoszczędzić innym kłopotów.

Odpowiedź Nassera Alshammariego jest najprostszym (i najszybszym) podejściem do uruchamiania aplikacji GTK wewnątrz kontenera Dockera - po prostu zamontuj gniazdo dla serwera X jako wolumin Dockera i powiedz Dockerowi, aby użył go zamiast tego.

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

(ja również zaleca się podanie flagi -u <username-within-container>, ponieważ uruchamianie aplikacji X11 jako root nie zawsze działa i generalnie nie jest zalecane, szczególnie {[12] } podczas współdzielenia sesji).

Będzie to działać w aplikacjach takich jak xterm, a także w aplikacjach opartych na GTK. Na przykład, jeśli spróbujesz tego z Firefoksem (który jest oparty na GTK), to zadziała (zauważ, że jeśli już uruchomiłeś Firefoksa na hoście, otworzy nowe okno na hoście, a nie otworzy nową instancję Firefoksa z wewnątrz Pojemnik).

Jednak, Twoja odpowiedź pyta konkretnie o PyQT. okazuje się, że Qt nie wspiera dzielenia sesji X w ten sposób (a przynajmniej nie wspiera tego dobrze).

Jeśli spróbujesz uruchomić w ten sposób aplikację opartą na QT, prawdopodobnie pojawi się błąd podobny do następującego:

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

Mówię "prawdopodobnie", ponieważ nie przetestowałem tego podejścia z wystarczającą ilością aplikacji Qt, aby mieć pewność, lub zagrzebałem się w kodzie źródłowym Qt na tyle, aby dowiedzieć się, dlaczego to nie jest obsługiwane. YMMV, i może Ci się poszczęści, ale jeśli chcesz uruchomić aplikację opartą na Qt z kontenera Dockera, być może będziesz musiał przejść "Staromodne" podejście i albo

  1. Uruchom sshd wewnątrz kontenera, włącz przekazywanie X11, a następnie połącz się z kontenerem za pomocą ssh -X (bardziej bezpieczne) lub ssh -Y (mniej bezpieczne, używane tylko, jeśli w pełni ufasz aplikacji w kontenerze).

  2. Uruchom VNC w kontenerze, oraz połącz się z nim z hosta za pomocą klienta VNC.

Pomiędzy tymi dwoma opcjami, polecam pierwszą, ale zobacz, która najlepiej pasuje do twojej sytuacji.

 16
Author: chimeracoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-08 20:37:16

Istnieje wiele rozwiązań, w których aplikacje GUI są uruchamiane w kontenerze dokera. Możesz na przykład użyć SSH lub VNC. Ale dodają trochę kosztów i opóźnienia. Najlepszym sposobem, jaki znalazłem, jest po prostu przekazanie pliku używanego przez serwer X w komputerze hosta jako woluminu do kontenera. Tak:

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

Wtedy wszystkie aplikacje GUI będą uruchamiane z kontenera.

Mam nadzieję, że to pomoże!
 8
Author: nasser alshammari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-07 15:18:57

Udało mi się uruchomić xeyes w kontenerze i zobaczyć "okno" w serwerze x działającym poza kontenerem. Oto jak:

Użyłem Xephyr do uruchomienia zagnieżdżonego serwera X. Nie jest to konieczne, ale większość pulpitów linuksowych domyślnie nie pozwala na uruchamianie zdalnych aplikacji na nich (tutaj's jak "naprawić" to na ubuntu).

Install Xephyr:

$ sudo apt-get install xserver-xephyr

Uruchom Xephyr:

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

Tworzy to nowe okno 800x600, które działa jak serwer X.

Znajdź adres" zewnętrzny" Twojej maszyny. Tutaj działa serwer 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)

Nie używaj 127.0.0.1! Możesz użyć każdego z pozostałych. Użyję 172.17.42.1.

Utwórz plik Dockerfile o następującej treści:

FROM ubuntu

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

CMD ["/usr/bin/xeyes"]

Zbuduj go:

$ docker build -t xeyes .

I uruchom go:

$ docker run -e DISPLAY=172.17.42.1:1.0 xeyes

Zauważ, że ustawiam zmienną środowiskową DISPLAY tam, gdzie chcę ją zobaczyć.

Możesz użyć tej samej techniki, aby przekierować wyświetlacz na dowolny serwer X.

 3
Author: ivant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-13 12:22:42

Możesz użyćsubuser do spakowania aplikacji GUI. Ma również dobre wsparcie dla aktualizacji aplikacji. Możesz umieścić swoje pliki Dockerfiles w repo git raz, a następnie po prostu uruchomić subuser update all Na każdym kliencie, aby odbudować obrazy, gdy trzeba je zmienić.

 1
Author: timthelion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-16 11:54:45

Ostatnio próbowałem uruchomić aplikację PyQt5 w dockerze. Dowiedziałem się, że nie można uruchomić aplikacji jako root (musisz utworzyć normalnego użytkownika). Jeśli chcesz odtwarzać audio / wideo w aplikacji, musisz uruchomić kontener docker z grupą "audio" i zamontować urządzenie dźwiękowe. Więc do uruchomienia aplikacji używam tego:

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

Spędziłem trochę czasu, aż zorientowałem się, jakie pakiety muszę dodać do mojego kontenera, aby uruchomić w nim aplikację PyQt, więc stworzyłem kilka plików Dockerfiles (z prostą aplikacją demo) aby ułatwić innym:

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

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

 1
Author: fadawar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-08 20:19:22