Können Sie GUI-Anwendungen in einem Docker-Container ausführen?

409

Wie können Sie GUI-Anwendungen in einem Docker- Container ausführen ?

Gibt es Bilder, die eingerichtet wurden vncserveroder so, dass Sie beispielsweise eine zusätzliche Speedbump-Sandbox hinzufügen können, z. B. Firefox?

Wille
quelle
Diese Frage scheint sich nur auf Linux (basierend auf Alter und Inhalt der Antworten) und nicht auf Windows zu beziehen. Wenn ja, können wir den Titel bearbeiten, um dies zu verdeutlichen? Danke
UuDdLrLrSs

Antworten:

238

Sie können einfach einen vncserver zusammen mit Firefox installieren :)

Ich habe ein Bild, vnc / Firefox, hier geschoben: docker pull creack/firefox-vnc

Das Bild wurde mit dieser Docker-Datei erstellt:

# Firefox over VNC
#
# VERSION               0.1
# DOCKER-VERSION        0.2

FROM    ubuntu:12.04
# Make sure the package repository is up to date
RUN     echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN     apt-get update

# Install vnc, xvfb in order to create a 'fake' display and firefox
RUN     apt-get install -y x11vnc xvfb firefox
RUN     mkdir ~/.vnc
# Setup a password
RUN     x11vnc -storepasswd 1234 ~/.vnc/passwd
# Autostart firefox (might not be the best way to do it, but it does the trick)
RUN     bash -c 'echo "firefox" >> /.bashrc'

Dadurch wird ein Docker-Container erstellt, auf dem VNC mit dem Kennwort ausgeführt wird 1234:

Für Docker Version 18 oder neuer:

docker run -p 5900:5900 -e HOME=/ creack/firefox-vnc x11vnc -forever -usepw -create

Für Docker Version 1.3 oder neuer:

docker run -p 5900 -e HOME=/ creack/firefox-vnc x11vnc -forever -usepw -create

Für Docker vor Version 1.3:

docker run -p 5900 creack/firefox-vnc x11vnc -forever -usepw -create
knarren
quelle
2
Wie würde ich einen VNC-Client verwenden, um dies aus der Ferne anzuzeigen? Das Eingeben des IP + -Ports scheint nicht zu funktionieren.
user94154
17
Zuerst müssen Sie den zugewiesenen Port überprüfen (indem Sie dies tun docker inspect <container id>oder einfach docker ps, dann stellen Sie mit dem gerade gefundenen Port eine Verbindung zur IP Ihres Hosts her.
Creack
9
Das Bild creackfirefox-vnc schlägt mit folgendem Fehler fehl: Geben Sie das VNC-Kennwort ein: stty: Standardeingabe: Unangemessenes ioctl für Geräte-Fgets: Keine solche Datei oder kein solches Verzeichnis stty: Standardeingabe: Unangemessenes ioctl für Gerät x11vnc -usepw: Es konnte kein zu verwendendes Kennwort gefunden werden.
Alfonsodev
6
Verwenden Sie Docker gut> Ausführen von GUI-Apps mit Docker fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker
Dennis C
7
Es gibt keinen Benutzernamen, das Passwort ist in der Antwort deutlich angegeben und jeder vnc-Client wird dies tun. In meinem Fall mag ich die native Osx. (Drücken Sie im Finder den Befehl + K und stellen Sie eine Verbindung zu vnc: // <Docker-IP>: <Container exponierter Port> her.)
Knacken Sie
195

Xauthority wird bei neueren Systemen zu einem Problem. Ich kann entweder jeden Schutz mit xhost + verwerfen, bevor ich meine Docker-Container ausführe, oder ich kann eine gut vorbereitete Xauthority-Datei übergeben. Typische Xauthority-Dateien sind hostnamenspezifisch. Mit Docker kann jeder Container einen anderen Hostnamen haben (mit Docker-Run -h festgelegt), aber selbst das Festlegen des Hostnamens des Containers, der mit dem Hostsystem identisch ist, hat in meinem Fall nicht geholfen. xeyes (ich mag dieses Beispiel) würde das magische Cookie einfach ignorieren und keine Anmeldeinformationen an den Server übergeben. Daher erhalten wir die Fehlermeldung 'Kein Protokoll angegeben Anzeige kann nicht geöffnet werden'

Die Xauthority-Datei kann so geschrieben werden, dass der Hostname keine Rolle spielt. Wir müssen die Authentifizierungsfamilie auf 'FamilyWild' setzen. Ich bin mir nicht sicher, ob xauth eine richtige Befehlszeile dafür hat. Hier ist ein Beispiel, das xauth und sed kombiniert, um dies zu tun. Wir müssen die ersten 16 Bits der nlist-Ausgabe ändern. Der Wert von FamilyWild ist 65535 oder 0xffff.

docker build -t xeyes - << __EOF__
FROM debian
RUN apt-get update
RUN apt-get install -qqy x11-apps
ENV DISPLAY :0
CMD xeyes
__EOF__
XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth
xauth nlist :0 | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
docker run -ti -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH -e XAUTHORITY=$XAUTH xeyes
Jürgen Weigert
quelle
8
Nur eine Anmerkung, -v $XSOCK:$XSOCK -v $XAUTH:$XAUTHkann verkürzt werden zu-v $XSOCK -v $XAUTH
Piotr Aleksander Chmielowski
2
@PiotrAleksanderChmielowski, der für mich nicht funktioniert hat, Docker Version 1.12.0, Build 8eab29e
TBBC0
14
@Dirk: Sie können ersetzen möchten :0mit $DISPLAY. Das heißt xauth nlist $DISPLAY | ...und docker run -ti -e DISPLAY=$DISPLAY .... Normalerweise ist das X DISPLAY :0, aber nicht immer (und besonders nicht, wenn Sie eine Verbindung über ssh -X herstellen).
Johndodo
4
Unter Ubuntu 16.04 erstellt xauth die /tmp/.docker.xauthDatei mit 600Berechtigungen. Dies führt dazu, dass xauth im Docker-Container die Datei nicht lesen kann. Sie können dies überprüfen, indem Sie es xauth listim Docker-Container ausführen. Ich habe chmod 755 $XAUTHnach dem xauth nlist :0 | ...Befehl hinzugefügt , um dies zu beheben.
Abai
2
@Abai Warum 755 verwenden, wenn 444 oder 644 ausreichen?
Daniel Alder
68

Ich habe gerade diesen Blogeintrag gefunden und möchte ihn hier mit Ihnen teilen, weil ich denke, dass dies der beste Weg ist und es so einfach ist.

http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/

PROS:
+ kein x Server-Zeug im Docker-Container
+ kein vnc-Client / Server erforderlich
+ kein ssh mit x-Weiterleitung
+ viel kleinere Docker-Container

Nachteile:
- Verwenden von x auf dem Host (nicht für sicheres Sandboxing gedacht)

Für den Fall, dass der Link eines Tages fehlschlägt, habe ich hier den wichtigsten Teil
eingefügt: Docker-Datei:

FROM ubuntu:14.04

RUN apt-get update && apt-get install -y firefox

# Replace 1000 with your user / group id
RUN export uid=1000 gid=1000 && \
    mkdir -p /home/developer && \
    echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
    echo "developer:x:${uid}:" >> /etc/group && \
    echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
    chmod 0440 /etc/sudoers.d/developer && \
    chown ${uid}:${gid} -R /home/developer

USER developer
ENV HOME /home/developer
CMD /usr/bin/firefox

Erstellen Sie das Bild:

docker build -t firefox .

und der Befehl run:

docker run -ti --rm \
   -e DISPLAY=$DISPLAY \
   -v /tmp/.X11-unix:/tmp/.X11-unix \
   firefox

Natürlich können Sie dies auch im Befehl run mit tun sh -c "echo script-here"

TIPP: Audio finden Sie unter: https://stackoverflow.com/a/28985715/2835523

A. Binzxxxxxx
quelle
Wie kann ich das unter Windows 7 machen? Muss ich einen X-Server installieren?
Walksignison
3
Da die meisten Antworten hier nur für Unix gelten, denke ich - bis Windows das X-Server-Fenstersystem unterstützt.
A. Binzxxxxxx
Glaubst du, es könnte funktionieren, wenn ich den X-Server unter Windows installiert oder sogar einen X-Server in meinen Docker-Container gebündelt hätte?
Walksignison
1
Ich denke, Sie müssen auch in Dockerfile installieren apt-get -y install sudo, um /etc/sudoers.dOrdner zu erstellen .
Mulg0r
1
Es kann auch erforderlich sein, Verbindungen zu X von jedem Host mit$ xhost +
Bandoos
52

Mit Docker-Datenvolumes ist es sehr einfach, den Unix-Domain-Socket von xorg im Container verfügbar zu machen.

Zum Beispiel mit einer Docker-Datei wie dieser:

FROM debian
RUN apt-get update
RUN apt-get install -qqy x11-apps
ENV DISPLAY :0
CMD xeyes

Sie können Folgendes tun:

$ docker build -t xeyes - < Dockerfile
$ XSOCK=/tmp/.X11-unix/X0
$ docker run -v $XSOCK:$XSOCK xeyes

Dies entspricht natürlich im Wesentlichen der X-Weiterleitung. Es gewährt dem Container vollen Zugriff auf den xserver auf dem Host. Es wird daher nur empfohlen, wenn Sie dem Inhalt vertrauen.

Hinweis: Wenn Sie Sicherheitsbedenken haben, besteht eine bessere Lösung darin, die App auf die obligatorische oder rollenbasierte Zugriffskontrolle zu beschränken . Docker erreicht eine ziemlich gute Isolation, wurde jedoch für einen anderen Zweck entwickelt. Verwenden Sie AppArmor , SELinux oder GrSecurity , die auf Ihr Problem zugeschnitten sind.

Aryeh Leib Taurog
quelle
5
Sie müssen auch den Zugriff von anderen Hosts auf den X-Server mit einem Tool wie xhost zulassen. Um es vollständig zu öffnen, verwenden Sie es xhost +auf dem Host.
Tully
3
@Tully nur xhost +localist notwendig. Es ist jedoch besser, die ~/.XauthorityDatei im Container verfügbar zu machen , damit sie sich selbst authentifizieren kann.
Aryeh Leib Taurog
3
Haben Sie es geschafft, es auf einem Mac zum Laufen zu bringen (mit boot2docker)?
Karl Forner
4
Dies funktionierte ziemlich gut für mich auf einem Ubuntu 14.04-Laptop mit Docker 1.5 früher; aber jetzt scheitert für mich unter Ubuntu 15.04, Docker 1.6.2, mit dem Fehler Can't open display: :0. Irgendwelche Ideen?
Cboettig
6
Früher habe ich xhost +si:localuser:$USERnur den Benutzer autorisiert, der den Container startet.
Nick Breen
26

Sie können auch den Unterbenutzer verwenden: https://github.com/timthelion/subuser

Auf diese Weise können Sie viele GUI-Apps in Docker packen. Firefox und Emacs wurden bisher getestet. Mit Firefox funktioniert webGL jedoch nicht. Chrom funktioniert überhaupt nicht.

EDIT: Sound funktioniert!

EDIT2: In der Zeit, seit ich dies zum ersten Mal gepostet habe, hat sich der Unterbenutzer stark weiterentwickelt. Ich habe jetzt eine Website unter subuser.org und ein neues Sicherheitsmodell für die Verbindung zu X11 über XPRA-Bridging .

Timthelion
quelle
3
Bitte beachten Sie, dass der Subuser noch sehr neu und relativ ungetestet ist. Wenn Sie auf Probleme stoßen, reichen Sie bitte Fehlerberichte ein!
Timthelion
Ich würde X11 vermeiden, wenn es eine Möglichkeit gibt. Ihre Killer-App würde den Tor-Proxy im Docker ausführen und einen vollständigen Browser mit Plugins in einem untergeordneten Docker ausführen, sodass durch Firewall usw. das gesamte Netzwerk über den Tor-Docker verdrängt wird. Dies würde Runden um das aktuelle Browser-Bundle laufen lassen, um die Benutzerfreundlichkeit des Webs zu gewährleisten, da Sie umfangreiche Inhalte durchlassen würden.
Wird
1
Ist das Problem für Sie mit der X11-Sicherheit? Oder möchten Sie, dass dies mit Windows funktioniert? Oder dass dies aus der Ferne funktionieren soll? Alles das oben Genannte? Ich denke, dass es durchaus möglich ist, dies mit vnc zum Laufen zu bringen (obwohl ich es nicht zur Standardmethode machen würde, da es eine Abhängigkeit von vnc hinzufügt). Es ist nicht wirklich möglich / sinnvoll, Subbenutzer remote arbeiten zu lassen. Es gibt auch Folgendes : github.com/rogaha/docker-desktop, aber aus den Fehlerberichten geht hervor, dass xpra im wirklichen Leben möglicherweise unbrauchbar ist.
Timthelion
24

OSX

Jürgen Weigert hat die beste Antwort, die für mich unter Ubuntu funktioniert hat. Unter OSX läuft Docker jedoch innerhalb von VirtualBox, sodass die Lösung ohne weitere Arbeit nicht funktioniert.

Ich habe es mit diesen zusätzlichen Zutaten zu tun:

  1. Xquartz (OSX wird nicht mehr mit X11-Server geliefert)
  2. Socket Forwarding mit Socat (Brew Install Socat)
  3. Bash-Skript zum Starten des Containers

Ich würde Benutzerkommentare begrüßen, um diese Antwort für OSX zu verbessern. Ich bin nicht sicher, ob die Socket-Weiterleitung für X sicher ist, aber meine beabsichtigte Verwendung besteht darin, den Docker-Container nur lokal auszuführen.

Außerdem ist das Skript insofern etwas fragil, als es nicht einfach ist, die IP-Adresse des Computers abzurufen, da es sich in unserem lokalen WLAN befindet und es sich also immer um eine zufällige IP handelt.

Das BASH-Skript, mit dem ich den Container starte:

#!/usr/bin/env bash

CONTAINER=py3:2016-03-23-rc3
COMMAND=/bin/bash
NIC=en0

# Grab the ip address of this box
IPADDR=$(ifconfig $NIC | grep "inet " | awk '{print $2}')

DISP_NUM=$(jot -r 1 100 200)  # random display number between 100 and 200

PORT_NUM=$((6000 + DISP_NUM)) # so multiple instances of the container won't interfer with eachother

socat TCP-LISTEN:${PORT_NUM},reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\" 2>&1 > /dev/null &

XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth.$USER.$$
touch $XAUTH
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -

docker run \
    -it \
    --rm \
    --user=$USER \
    --workdir="/Users/$USER" \
    -v "/Users/$USER:/home/$USER:rw" \
    -v $XSOCK:$XSOCK:rw \
    -v $XAUTH:$XAUTH:rw \
    -e DISPLAY=$IPADDR:$DISP_NUM \
    -e XAUTHORITY=$XAUTH \
    $CONTAINER \
    $COMMAND

rm -f $XAUTH
kill %1       # kill the socat job launched above

Ich kann xeyes und matplotlib dazu bringen, mit diesem Ansatz zu arbeiten.

Windows 7+

Unter Windows 7+ ist es mit MobaXterm etwas einfacher:

  1. Installieren Sie MobaXterm für Windows
  2. Starten Sie MobaXterm
  3. X-Server konfigurieren: Einstellungen -> X11 (Registerkarte) -> X11-Fernzugriff auf voll setzen
  4. Verwenden Sie dieses BASH-Skript, um den Container zu starten

run_docker.bash::

#!/usr/bin/env bash

CONTAINER=py3:2016-03-23-rc3
COMMAND=/bin/bash
DISPLAY="$(hostname):0"
USER=$(whoami)

docker run \
    -it \
    --rm \
    --user=$USER \
    --workdir="/home/$USER" \
    -v "/c/Users/$USER:/home/$USER:rw" \
    -e DISPLAY \
    $CONTAINER \
    $COMMAND

xeyes läuft auf dem PC

Nick
quelle
Ich habe nicht verstanden, was Sie mit dem Bash-Skript gemeint haben - wie führe ich es in Windows aus?
Deller
@deller Ich mache Softwareentwicklung unter Windows mit GIT, daher steht mir die GIT-Bash-Shell zur Verfügung.
Nick
Ich folgte den Schritten. Ich bekomme jedoch error: XDG_RUNTIME_DIR not set in the environment.und Error: cannot open display: VAIO:0.0. Haben Sie so etwas erlebt?
user3275095
1
Ich erhalte eine Fehlermeldung, dass der Benutzer nicht gefunden wurde, z. B. "Keine übereinstimmenden Einträge in der passwd-Datei".
Walksignison
19

Das Teilen der Hostanzeige: 0 hat, wie in einigen anderen Antworten angegeben, zwei Nachteile:

  • Aufgrund einiger X-Sicherheitslecks wird die Containerisolation unterbrochen. Zum Beispiel Keylogging mit xevoder xinputist möglich und Fernsteuerung von Hostanwendungen mit xdotool.
  • Anwendungen können Rendering-Störungen und fehlerhafte RAM-Zugriffsfehler aufweisen, da der gemeinsam genutzte Speicher für die X-Erweiterung MIT-SHM fehlt. (Kann auch mit der Option zur Verschlechterung der Isolation behoben werden --ipc=host).

Unten finden Sie ein Beispielskript zum Ausführen eines Docker-Images in Xephyr, mit dem dieses Problem behoben wird.

  • Es vermeidet X-Sicherheitslecks, da die Docker-Anwendungen auf einem verschachtelten X-Server ausgeführt werden.
  • MIT-SHM ist deaktiviert, um RAM-Zugriffsfehler zu vermeiden.
  • Die Containersicherheit wird mit verbessert --cap-drop ALL --security-opt no-new-privileges. Auch der Containerbenutzer ist nicht root.
  • Ein X-Cookie wird erstellt, um den Zugriff auf die Xephyr-Anzeige einzuschränken.

Das Skript erwartet einige Argumente, zum einen einen Host-Fenstermanager in Xephyr, zum anderen ein Docker-Image und zum dritten einen auszuführenden Image-Befehl. Verwenden Sie zum Ausführen einer Desktop-Umgebung in Docker ":" anstelle eines Host-Fenstermanagers.

Durch Schließen des Xephyr-Fensters werden Docker-Container-Anwendungen beendet. Durch das Beenden der Docker-Anwendungen wird das Xephyr-Fenster geschlossen.

Beispiele:

  • xephyrdocker "openbox --sm-disable" x11docker/lxde pcmanfm
  • xephyrdocker : x11docker/lxde
  • xephyrdocker xfwm4 --device /dev/snd jess/nes /games/zelda.rom

xephyrdocker-Skript:

#! /bin/bash
#
# Xephyrdocker:     Example script to run docker GUI applications in Xephyr.
#
# Usage:
#   Xephyrdocker WINDOWMANAGER DOCKERIMAGE [IMAGECOMMAND [ARGS]]
#
# WINDOWMANAGER     host window manager for use with single GUI applications.
#                   To run without window manager from host, use ":"
# DOCKERIMAGE       docker image containing GUI applications or a desktop
# IMAGECOMMAND      command to run in image
#
Windowmanager="$1" && shift
Dockerimage="$*"

# Container user
Useruid=$(id -u)
Usergid=$(id -g)
Username="$(id -un)"
[ "$Useruid" = "0" ] && Useruid=1000 && Usergid=1000 && Username="user$Useruid"

# Find free display number
for ((Newdisplaynumber=1 ; Newdisplaynumber <= 100 ; Newdisplaynumber++)) ; do
  [ -e /tmp/.X11-unix/X$Newdisplaynumber ] || break
done
Newxsocket=/tmp/.X11-unix/X$Newdisplaynumber

# cache folder and files
Cachefolder=/tmp/Xephyrdocker_X$Newdisplaynumber
[ -e "$Cachefolder" ] && rm -R "$Cachefolder"
mkdir -p $Cachefolder
Xclientcookie=$Cachefolder/Xcookie.client
Xservercookie=$Cachefolder/Xcookie.server
Xinitrc=$Cachefolder/xinitrc
Etcpasswd=$Cachefolder/passwd

# command to run docker
# --rm                               created container will be discarded.
# -e DISPLAY=$Newdisplay             set environment variable to new display
# -e XAUTHORITY=/Xcookie             set environment variable XAUTHORITY to provided cookie
# -v $Xclientcookie:/Xcookie:ro      provide cookie file to container
# -v $NewXsocket:$NewXsocket:ro      Share new X socket of Xephyr
# --user $Useruid:$Usergid           Security: avoid root in container
# -v $Etcpasswd:/etc/passwd:ro       /etc/passwd file with user entry
# --group-add audio                  Allow access to /dev/snd if shared with '--device /dev/snd' 
# --cap-drop ALL                     Security: disable needless capabilities
# --security-opt no-new-privileges   Security: forbid new privileges
Dockercommand="docker run --rm \
  -e DISPLAY=:$Newdisplaynumber \
  -e XAUTHORITY=/Xcookie \
  -v $Xclientcookie:/Xcookie:ro \
  -v $Newxsocket:$Newxsocket:rw \
  --user $Useruid:$Usergid \
  -v $Etcpasswd:/etc/passwd:ro \
  --group-add audio \
  --env HOME=/tmp \
  --cap-drop ALL \
  --security-opt no-new-privileges \
  $(command -v docker-init >/dev/null && echo --init) \
  $Dockerimage"

echo "docker command: 
$Dockercommand
"

# command to run Xorg or Xephyr
# /usr/bin/Xephyr                an absolute path to X server executable must be given for xinit
# :$Newdisplaynumber             first argument has to be new display
# -auth $Xservercookie           path to cookie file for X server. Must be different from cookie file of client, not sure why
# -extension MIT-SHM             disable MIT-SHM to avoid rendering glitches and bad RAM access (+ instead of - enables it)
# -nolisten tcp                  disable tcp connections for security reasons
# -retro                         nice retro look
Xcommand="/usr/bin/Xephyr :$Newdisplaynumber \
  -auth $Xservercookie \
  -extension MIT-SHM \
  -nolisten tcp \
  -screen 1000x750x24 \
  -retro"

echo "X server command:
$Xcommand
"

# create /etc/passwd with unprivileged user
echo "root:x:0:0:root:/root:/bin/sh" >$Etcpasswd
echo "$Username:x:$Useruid:$Usergid:$Username,,,:/tmp:/bin/sh" >> $Etcpasswd

# create xinitrc
{ echo "#! /bin/bash"

  echo "# set environment variables to new display and new cookie"
  echo "export DISPLAY=:$Newdisplaynumber"
  echo "export XAUTHORITY=$Xclientcookie"

  echo "# same keyboard layout as on host"
  echo "echo '$(setxkbmap -display $DISPLAY -print)' | xkbcomp - :$Newdisplaynumber"

  echo "# create new XAUTHORITY cookie file" 
  echo ":> $Xclientcookie"
  echo "xauth add :$Newdisplaynumber . $(mcookie)"
  echo "# create prepared cookie with localhost identification disabled by ffff,"
  echo "# needed if X socket is shared instead connecting over tcp. ffff means 'familiy wild'"
  echo 'Cookie=$(xauth nlist '":$Newdisplaynumber | sed -e 's/^..../ffff/')" 
  echo 'echo $Cookie | xauth -f '$Xclientcookie' nmerge -'
  echo "cp $Xclientcookie $Xservercookie"
  echo "chmod 644 $Xclientcookie"

  echo "# run window manager in Xephyr"
  echo $Windowmanager' & Windowmanagerpid=$!'

  echo "# show docker log"
  echo 'tail --retry -n +1 -F '$Dockerlogfile' 2>/dev/null & Tailpid=$!'

  echo "# run docker"
  echo "$Dockercommand"
} > $Xinitrc

xinit  $Xinitrc -- $Xcommand
rm -Rf $Cachefolder

Dieses Skript wird im x11docker-Wiki verwaltet . Ein erweitertes Skript ist x11docker , das auch Funktionen wie GPU-Beschleunigung, Webcam- und Druckerfreigabe usw. unterstützt.

mviereck
quelle
18

Hier ist eine einfache Lösung, mit der Sie keinen XServer, vncServer oder sshdDämon auf dem Container installieren müssen . Was es an Einfachheit gewinnt, verliert es an Sicherheit und Isolation.

Er geht davon aus, dass Sie auf dem Host - Rechner eine Verbindung über sshmit X11Weiterleitung.

Fügen Sie in der sshdKonfiguration des Hosts die Zeile hinzu

X11UseLocalhost no

Damit wird der weitergeleitete X-Server-Port auf dem Host auf allen Schnittstellen (nicht nur lo) und insbesondere auf der virtuellen Docker-Schnittstelle geöffnet docker0.

Der Container benötigt beim Ausführen Zugriff auf die .XauthorityDatei, damit er eine Verbindung zum Server herstellen kann. Zu diesem Zweck definieren wir ein schreibgeschütztes Volume, das auf das Home-Verzeichnis auf dem Host verweist (möglicherweise keine gute Idee!), Und setzen die XAUTHORITYVariable entsprechend.

docker run -v $HOME:/hosthome:ro -e XAUTHORITY=/hosthome/.Xauthority

Das reicht nicht aus, wir müssen auch die Variable DISPLAY vom Host übergeben, aber den Hostnamen durch die IP ersetzen:

-e DISPLAY=$(echo $DISPLAY | sed "s/^.*:/$(hostname -i):/")

Wir können einen Alias ​​definieren:

 alias dockerX11run='docker run -v $HOME:/hosthome:ro -e XAUTHORITY=/hosthome/.Xauthority -e DISPLAY=$(echo $DISPLAY | sed "s/^.*:/$(hostname -i):/")'

Und testen Sie es so:

dockerX11run centos xeyes
danidiaz
quelle
2
(Dies ist ideal für vertrauenswürdige Apps. Für jede Art von Sandboxing möchten Sie jedoch X-Forwarding vermeiden.)
Will
1
Wenn Sie nicht das gesamte Home-Verzeichnis in den Container einbinden möchten, können Sie einfach die .XauthorityDatei selbst einbinden : -v $HOME/.Xauthority:/root/.Xauthority -e XAUTHORITY=/root/.Xauthority.
Robert Haines
2
Anstatt zu ändern X11UseLocalhost, können Sie auch die zusätzliche Option --net=hostfür den docker runBefehl verwenden ( hier zu finden ).
ingomueller.net
--net=hostist eine schlechte Idee, denn wenn Sie jetzt einen Port im Container öffnen, wird er auch im Host geöffnet ...
MrR
16

Während die Antwort von Jürgen Weigert im Wesentlichen diese Lösung abdeckt, war mir zunächst nicht klar, was dort beschrieben wurde. Also werde ich meine Meinung dazu hinzufügen, falls jemand anderes eine Klärung benötigt.

Die relevante Dokumentation ist zunächst die X-Sicherheitsmanpage .

Zahlreiche Online-Quellen schlagen vor, nur den X11-Unix-Socket und die ~/.XauthorityDatei in den Container zu mounten. Diese Lösungen funktionieren oft durch Glück, ohne wirklich zu verstehen, warum beispielsweise der Containerbenutzer dieselbe UID wie der Benutzer hat, sodass keine Berechtigung für magische Schlüssel erforderlich ist.

Zunächst einmal hat die Xauthority-Datei den Modus 0600, sodass der Containerbenutzer sie nur lesen kann, wenn sie dieselbe UID hat.

Selbst wenn Sie die Datei in den Container kopieren und den Besitz ändern, gibt es noch ein weiteres Problem. Wenn Sie xauth listauf dem Host und dem Container mit derselben XauthorityDatei ausgeführt werden, werden verschiedene Einträge aufgelistet. Dies liegt daran xauth, dass die Einträge je nach Ausführungsort gefiltert werden.

Der X-Client im Container (dh die GUI-App) verhält sich genauso wie xauth. Mit anderen Worten, das magische Cookie für die X-Sitzung wird nicht auf dem Desktop des Benutzers ausgeführt. Stattdessen werden die Einträge für alle "Remote" X-Sitzungen angezeigt, die Sie zuvor geöffnet haben (siehe unten).

Sie müssen also einen neuen Eintrag mit dem Hostnamen des Containers und demselben Hex-Schlüssel wie das Host-Cookie hinzufügen (dh die X-Sitzung, die auf Ihrem Desktop ausgeführt wird), z.

containerhostname/unix:0   MIT-MAGIC-COOKIE-1   <shared hex key>

Der Haken ist, dass der Cookie im xauth addInneren des Behälters hinzugefügt werden muss :

touch ~/.Xauthority
xauth add containerhostname/unix:0 . <shared hex key>

Andernfalls wird es so xauthmarkiert, dass es nur außerhalb des Containers angezeigt wird.

Das Format für diesen Befehl lautet:

xauth add hostname/$DISPLAY protocol hexkey

Wo .steht das MIT-MAGIC-COOKIE-1Protokoll.

Hinweis: Es ist nicht erforderlich, .Xauthorityden Container zu kopieren oder zu binden . Erstellen Sie einfach eine leere Datei, wie gezeigt, und fügen Sie das Cookie hinzu.

Die Antwort von Jürgen Weigert umgeht dies, indem er mithilfe des FamilyWildVerbindungstyps eine neue Berechtigungsdatei auf dem Host erstellt und in den Container kopiert. Beachten Sie, dass zuerst der Hex-Schlüssel für die aktuelle X-Sitzung aus der ~/.XauthorityVerwendung extrahiert wird xauth nlist.

Die wesentlichen Schritte sind also:

  • Extrahieren Sie den Hex-Schlüssel des Cookies für die aktuelle X-Sitzung des Benutzers.
  • Erstellen Sie eine neue Xauthority-Datei im Container mit dem Hostnamen des Containers und dem gemeinsam genutzten Hex-Schlüssel (oder erstellen Sie ein Cookie mit dem FamilyWildVerbindungstyp).

Ich gebe zu, dass ich nicht sehr gut verstehe, wie es FamilyWildfunktioniert oder wie oder wie xauthX-Clients Einträge aus der Xauthority-Datei filtern, je nachdem, wo sie ausgeführt werden. Zusätzliche Informationen hierzu sind willkommen.

Wenn Sie Ihre Docker-App verteilen möchten, benötigen Sie ein Startskript zum Ausführen des Containers, der den Hex-Schlüssel für die X-Sitzung des Benutzers erhält, und importiert ihn auf eine der beiden zuvor erläuterten Arten in den Container.

Es hilft auch, die Mechanismen des Autorisierungsprozesses zu verstehen:

  • Ein X-Client (dh eine GUI-Anwendung), der im Container ausgeführt wird, sucht in der Xauthority-Datei nach einem Cookie-Eintrag, der dem Hostnamen des Containers und dem Wert von entspricht $DISPLAY.
  • Wenn ein übereinstimmender Eintrag gefunden wird, leitet der X-Client ihn mit seiner Autorisierungsanforderung über den entsprechenden Socket in dem /tmp/.X11-unixim Container bereitgestellten Verzeichnis an den X-Server weiter .

Hinweis: Der X11 Unix-Socket muss noch im Container bereitgestellt werden, da der Container sonst keine Route zum X-Server hat. Die meisten Distributionen deaktivieren aus Sicherheitsgründen standardmäßig den TCP-Zugriff auf den X-Server.

Für zusätzliche Informationen und um besser zu verstehen, wie die X-Client / Server-Beziehung funktioniert, ist es auch hilfreich, den Beispielfall der SSH X-Weiterleitung zu betrachten:

  • Der auf einem Remotecomputer ausgeführte SSH-Server emuliert seinen eigenen X-Server.
  • Der Wert von $DISPLAYin der SSH-Sitzung wird so festgelegt, dass er auf den eigenen X-Server verweist.
  • Es wird verwendet xauth, um ein neues Cookie für den Remote-Host zu erstellen und es den XauthorityDateien sowohl für den lokalen als auch für den Remote-Benutzer hinzuzufügen.
  • Wenn GUI-Apps gestartet werden, kommunizieren sie mit dem emulierten X-Server von SSH.
  • Der SSH-Server leitet diese Daten an den SSH-Client auf Ihrem lokalen Desktop zurück.
  • Der lokale SSH-Client sendet die Daten an die X-Server-Sitzung, die auf Ihrem Desktop ausgeführt wird, als wäre der SSH-Client tatsächlich ein X-Client (dh eine GUI-App).
  • Der X-Server verwendet die empfangenen Daten, um die GUI auf Ihrem Desktop zu rendern.
  • Zu Beginn dieses Austauschs sendet der Remote-X-Client auch eine Autorisierungsanforderung unter Verwendung des gerade erstellten Cookies. Der lokale X-Server vergleicht es mit seiner lokalen Kopie.
orodbhen
quelle
12

Dies ist nicht leicht, aber eine nette Lösung, die Docker-Feature-Parität mit vollständiger Desktop-Virtualisierung bietet. Sowohl Xfce4 als auch IceWM für Ubuntu und CentOS funktionieren, und die noVNCOption ermöglicht einen einfachen Zugriff über einen Browser.

https://github.com/ConSol/docker-headless-vnc-container

Es läuft noVNCgenauso gut wie tigerVNCder vncserver. Dann wird ein startxbestimmter Fenstermanager aufgerufen. Darüber hinaus libnss_wrapper.sowird die Kennwortverwaltung für die Benutzer emuliert.

schneidig
quelle
hat jemand das getestet?
Guilhermecgs
3
@guilhermecgs ja, und funktioniert gut. Seitdem habe ich auch xpraDocker ausprobiert , das X ohne Root ist. Es xprawar die am besten geeignete IMO und ist effizienter als VNC.
Bindestrich
Nur um klar zu sein ... Kann ich mit diesem Bild eine vollständige Desktop-Erfahrung (GNOME, KDE) machen?
Guilhermecgs
Ich habe nur Xfce4 und IceWM ausprobiert (was in diesem Repo enthalten ist). Natürlich ist die Erfahrung begrenzt, zum Beispiel werden Mount-Geräte nicht auf dem Desktop (gvfs) angezeigt, es sei denn, Sie übergeben sie --device /dev/...an das Docker und legen die erforderlichen --capBerechtigungen fest. Das macht den Zweck der Eindämmung zunichte, aber Sie können Geräte passieren. Mit einigen Optimierungen sollte es möglich sein, GNOME / KDE unter VNC auszuführen. Ich habe mehrere X im Docker mit NVIDIA-Karten (kein VNC oder Xpra) ausgeführt, so dass dies sicherlich machbar ist.
Bindestrich
Wir haben es bisher nicht versucht. Die größte Herausforderung dabei wäre, einen funktionierenden D-Bus-Daemon aufzurufen. Die meisten Gnome- oder KDE-Desktops benötigen sie. Möge das ubuntu-desktop-lxde-vnc- Projekt Ihnen dort helfen.
toschneck
11

Die unter http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/ angegebene Lösung scheint eine einfache Möglichkeit zu sein, GUI-Anwendungen aus den Containern heraus zu starten (ich habe es mit Firefox versucht über Ubuntu 14.04), aber ich habe festgestellt, dass eine kleine zusätzliche Änderung an der vom Autor veröffentlichten Lösung erforderlich ist.

Insbesondere zum Ausführen des Containers hat der Autor Folgendes erwähnt:

    docker run -ti --rm \
    -e DISPLAY=$DISPLAY \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    firefox

Aber ich fand, dass (basierend auf einem bestimmten Kommentar auf der gleichen Seite) zwei zusätzliche Optionen

    -v $HOME/.Xauthority:$HOME/.Xauthority

und

    -net=host 

müssen beim Ausführen des Containers angegeben werden, damit Firefox ordnungsgemäß funktioniert:

    docker run -ti --rm \
    -e DISPLAY=$DISPLAY \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -v $HOME/.Xauthority:$HOME/.Xauthority \
    -net=host \
    firefox

Ich habe ein Docker-Bild mit den Informationen auf dieser Seite und diesen zusätzlichen Ergebnissen erstellt: https://hub.docker.com/r/amanral/ubuntu-firefox/

Anshuman Manral
quelle
3
Ich habe festgestellt, dass Sie nicht einmal die /tmp/.X11-unixSteckdose passieren müssen . Es funktioniert nur mit Montage .Xauthorityund --net=host.
CMCDragonkai
2
Dies ist tatsächlich die einzige Lösung, die heutzutage funktioniert. Die Verwendung /tmp/.X11-unixals Volume funktioniert nicht mehr, da Docker die Bereitstellung von Volumes aus klebrigen Verzeichnissen stillschweigend ablehnt.
Christian Hujer
1
Ich denke, es hängt davon ab, welche Distribution Sie verwenden. Sie können den X11 Unix-Socket definitiv unter CentOS binden. Es ist auch wichtig zu verstehen, was --network=hosttut. Dadurch erhält Ihr Container vollen Zugriff auf den Netzwerkstapel des Hosts, was je nach dem, was Sie versuchen, unerwünscht sein kann. Wenn Sie nur daran arbeiten, containerisierte GUIs auf Ihrem Desktop auszuführen, sollte dies keine Rolle spielen.
Orodbhen
7

Es gibt eine andere Lösung von lord.garbage , um GUI-Apps in einem Container ohne VNC- , SSH- und X11-Weiterleitung auszuführen. Es wird auch hier erwähnt .

Niutech
quelle
1
Dies ist großartig, wenn Sicherheit kein Problem darstellt. Wenn Sie etwas andocken möchten, um es zu isolieren, vermeiden Sie am besten das Ein- und Aussteigen von X11 aus dem Container.
Wird
7

Wenn Sie eine GUI-Anwendung ohne Kopf ausführen möchten, lesen Sie hier . Sie müssen lediglich einen virtuellen Monitor mit xvfboder einer ähnlichen Software erstellen . Dies ist sehr hilfreich, wenn Sie Selenium-Tests beispielsweise mit Browsern ausführen möchten.

Nirgendwo erwähnt wird, dass einige Software selbst Sandboxing mit Linux-Containern verwenden. So wird beispielsweise Chrome niemals normal ausgeführt, wenn Sie --privilegedbeim Ausführen des Containers nicht das entsprechende Flag verwenden .

Pithikos
quelle
6

Ich bin zu spät zur Party, aber für Mac-Benutzer, die den XQuartz-Pfad nicht beschreiten möchten, ist hier ein funktionierendes Beispiel, das ein Fedora-Image mit einer Desktop-Umgebung (xfce) erstellt, die Xvfbund verwendet VNC. Es ist einfach und funktioniert:

Auf einem Mac können Sie einfach mit der Bildschirmfreigabe (Standard) darauf zugreifen und eine Verbindung herstellen localhost:5901.

Dockerfile:

FROM fedora

USER root

# Set root password, so I know it for the future
RUN echo "root:password123" | chpasswd

# Install Java, Open SSL, etc.
RUN dnf update -y --setopt=deltarpm=false  \
 && dnf install -y --setopt=deltarpm=false \
                openssl.x86_64             \
                java-1.8.0-openjdk.x86_64  \
                xorg-x11-server-Xvfb       \
                x11vnc                     \
                firefox                    \
                @xfce-desktop-environment  \
 && dnf clean all

# Create developer user (password: password123, uid: 11111)
RUN useradd -u 11111 -g users -d /home/developer -s /bin/bash -p $(echo password123 | openssl passwd -1 -stdin) developer

# Copy startup script over to the developer home
COPY start-vnc.sh /home/developer/start-vnc.sh
RUN chmod 700 /home/developer/start-vnc.sh
RUN chown developer.users /home/developer/start-vnc.sh

# Expose VNC, SSH
EXPOSE 5901 22

# Set up VNC Password and DisplayEnvVar to point to Display1Screen0
USER developer
ENV  DISPLAY :1.0
RUN  mkdir ~/.x11vnc
RUN  x11vnc -storepasswd letmein ~/.x11vnc/passwd

WORKDIR /home/developer
CMD ["/home/developer/start-vnc.sh"]

start-vnc.sh

#!/bin/sh

Xvfb :1 -screen 0 1024x768x24 &
sleep 5
x11vnc -noxdamage -many -display :1 -rfbport 5901 -rfbauth ~/.x11vnc/passwd -bg
sleep 2
xfce4-session &

bash
# while true; do sleep 1000; done

Überprüfen Sie die verknüpfte Readme-Datei auf Build- und Run-Befehle, wenn Sie möchten / benötigen.

Vince
quelle
5

Aufgrund der Antwort von Jürgen Weigert habe ich einige Verbesserungen:

docker build -t xeyes - << __EOF__
FROM debian
RUN apt-get update
RUN apt-get install -qqy x11-apps
ENV DISPLAY :0
CMD xeyes
__EOF__
XSOCK=/tmp/.X11-unix
XAUTH_DIR=/tmp/.docker.xauth
XAUTH=$XAUTH_DIR/.xauth
mkdir -p $XAUTH_DIR && touch $XAUTH
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
docker run -ti -v $XSOCK:$XSOCK -v $XAUTH_DIR:$XAUTH_DIR -e XAUTHORITY=$XAUTH xeyes

Der einzige Unterschied besteht darin, dass ein Verzeichnis $ XAUTH_DIR erstellt wird, in dem die Datei $ XAUTH abgelegt und das Verzeichnis $ XAUTH_DIR anstelle der Datei $ XAUTH in den Docker-Container eingefügt wird.

Der Vorteil dieser Methode besteht darin, dass Sie in /etc/rc.local einen Befehl schreiben können, mit dem ein leerer Ordner mit dem Namen $ XAUTH_DIR in / tmp erstellt und dessen Modus auf 777 geändert wird.

tr '\n' '\000' < /etc/rc.local | sudo tee /etc/rc.local >/dev/null
sudo sed -i 's|\x00XAUTH_DIR=.*\x00\x00|\x00|' /etc/rc.local >/dev/null
tr '\000' '\n' < /etc/rc.local | sudo tee /etc/rc.local >/dev/null
sudo sed -i 's|^exit 0.*$|XAUTH_DIR=/tmp/.docker.xauth; rm -rf $XAUTH_DIR; install -m 777 -d $XAUTH_DIR\n\nexit 0|' /etc/rc.local

Beim Neustart des Systems stellt Docker vor der Benutzeranmeldung das Verzeichnis $ XAUTH_DIR automatisch bereit, wenn die Neustartrichtlinie des Containers "immer" lautet. Nach der Benutzeranmeldung können Sie einen Befehl in ~ / .profile schreiben, mit dem die $ XAUTH-Datei erstellt werden soll. Der Container verwendet dann automatisch diese $ XAUTH-Datei.

tr '\n' '\000' < ~/.profile | sudo tee ~/.profile >/dev/null
sed -i 's|\x00XAUTH_DIR=.*-\x00|\x00|' ~/.profile
tr '\000' '\n' < ~/.profile | sudo tee ~/.profile >/dev/null
echo "XAUTH_DIR=/tmp/.docker.xauth; XAUTH=\$XAUTH_DIR/.xauth; touch \$XAUTH; xauth nlist \$DISPLAY | sed -e 's/^..../ffff/' | xauth -f \$XAUTH nmerge -" >> ~/.profile

Schließlich erhält der Container bei jedem Neustart des Systems und bei der Benutzeranmeldung automatisch die Xauthority-Datei.

Allenyllee
quelle
4

Die anderen Lösungen sollten funktionieren, aber hier ist eine Lösung für docker-compose.

Um diesen Fehler zu beheben, müssen Sie $ DISPLAY und .X11-unix an Docker übergeben und dem Benutzer, der Docker gestartet hat, Zugriff auf xhost gewähren.

Innerhalb der docker-compose.ymlDatei:

version: '2'
services:
    node:
        build: .
        container_name: node
        environment:
            - DISPLAY
        volumes:
            - /tmp/.X11-unix:/tmp/.X11-unix

Im Terminal oder Skript:

  • xhost +si:localuser:$USER
  • xhost +local:docker
  • export DISPLAY=$DISPLAY
  • docker-compose up
Leere
quelle
3

Verwenden Sie für OpenGL-Rendering mit dem Nvidia-Treiber das folgende Bild:

https://github.com/thewtex/docker-opengl-nvidia

Stellen Sie bei anderen OpenGL-Implementierungen sicher, dass das Image dieselbe Implementierung wie der Host hat.

Matt McCormick
quelle
3

Sie können dem Docker-Benutzer (hier: root) den Zugriff auf die X11-Anzeige ermöglichen:

XSOCK=/tmp/.X11-unix
xhost +SI:localuser:root 
docker run -t -i --rm -v $XSOCK:$XSOCK:ro -e DISPLAY=unix$(DISPLAY) image 
xhost -SI:localuser:root
wedesoft
quelle
2

OSX (10.13.6, High Sierra)

Ähnlich wie @Nicks Antwort, aber seine Lösung hat bei mir nicht funktioniert.

Installieren Sie zuerst socat, indem Sie dies tun brew install socat, und installieren Sie XQuartz ( https://www.xquartz.org/ ).

Befolgen Sie dann diese Schritte hier ( http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/ ) im Kommentarbereich:

1. in one mac terminal i started:

socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"

2. and in another mac terminal I ran:

docker run -ti --rm \
-e DISPLAY=$(ipconfig getifaddr en0):0 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
firefox

Ich konnte CLion auch von meinem Debian-Docker-Container aus starten.

nommer
quelle
1

Docker mit BRIDGE-Netzwerk. für Ubuntu 16.04 mit Display Manager lightdm:

cd /etc/lightdm/lightdm.conf.d
sudo nano user.conf

[Seat:*]
xserver-allow-tcp=true
xserver-command=X -listen tcp

Sie können mehr private Berechtigungen verwenden

xhost +

docker run --volume="$HOME/.Xauthority:/root/.Xauthority:rw" --env="DISPLAY=$HOST_IP_IN_BRIDGE_NETWORK:0" --net=bridge $container_name
Dabizharoman
quelle
1

Noch eine Antwort für den Fall, dass Sie das Image bereits erstellt haben:

  1. Docker ohne Sudo aufrufen ( So beheben Sie Docker: Problem mit Berechtigung verweigert )

  2. Teilen Sie den gleichen USER & home & passwd zwischen Host- und Container-Share (Tipps: Verwenden Sie die Benutzer-ID anstelle des Benutzernamens).

  3. Der Dev-Ordner für treiberabhängige Bibliotheken funktioniert einwandfrei

  4. plus X11 vorwärts.

    docker run --name=CONTAINER_NAME --network=host --privileged \
      -v /dev:/dev \
      -v `echo ~`:/home/${USER} \
      -p 8080:80 \
      --user=`id -u ${USER}` \
      --env="DISPLAY" \
      --volume="/etc/group:/etc/group:ro" \
      --volume="/etc/passwd:/etc/passwd:ro" \
      --volume="/etc/shadow:/etc/shadow:ro" \
      --volume="/etc/sudoers.d:/etc/sudoers.d:ro" \
      --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
      -it REPO:TAG /bin/bash

Sie fragen sich vielleicht, was bringt es, Docker zu verwenden, wenn so viele Dinge gleich sind? Ein Grund, den ich mir vorstellen kann, ist die Überwindung der Hölle der Paketabhängigkeit ( https://en.wikipedia.org/wiki/Dependency_hell) ).

Daher ist diese Art der Verwendung meiner Meinung nach eher für Entwickler geeignet.

TingQian LI
quelle
Dies ist der einzige, der für mich funktionieren würde. Für meine Zwecke konnte ich es auf Folgendes minimieren: Docker-Ausführung --network = host --volume = echo ~: / home / $ {USER} --user = id -u ${USER}--env = "DISPLAY" --volume = "/ etc. / passwd: / etc / passwd: ro "-it REPO: TAG / bin / bash
user1145922
1

Ich habe mithilfe von opencvin einen Videostream von einer USB-Kamera ausgeführt, indem ich die dockerfolgenden Schritte ausgeführt habe:

  1. Lassen Sie Docker auf den X-Server zugreifen

    xhost +local:docker
    
  2. Erstellen Sie den X11 Unix-Socket und die X-Authentifizierungsdatei

    XSOCK=/tmp/.X11-unix
    XAUTH=/tmp/.docker.xauth
    
  3. Fügen Sie die richtigen Berechtigungen hinzu

    xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
    
  4. Stellen Sie die Qt-Rendergeschwindigkeit auf "native" ein, damit die X11-Rendering-Engine nicht umgangen wird

    export QT_GRAPHICSSYSTEM=native
    
  5. Weisen Sie Qt an, MIT-SHM (Shared Memory) nicht zu verwenden. Auf diese Weise sollte es auch sicherer sein

    export QT_X11_NO_MITSHM=1
    
  6. Aktualisieren Sie den Docker-Ausführungsbefehl

    docker run -it \
               -e DISPLAY=$DISPLAY \
               -e XAUTHORITY=$XAUTH \
               -v $XSOCK:$XSOCK \
               -v $XAUTH:$XAUTH \
               --runtime=nvidia \
               --device=/dev/video0:/dev/video0 \
               nvcr.io/nvidia/pytorch:19.10-py3
    

Hinweis: Wenn Sie das Projekt abgeschlossen haben, geben Sie die Zugriffssteuerungen auf ihren Standardwert zurück. xhost -local:docker

Weitere Details: Verwenden von GUIs mit Docker

Gutschrift: Echtzeit- und Videoverarbeitungsobjekterkennung mit Tensorflow, OpenCV und Docker

tsveti_iko
quelle
"X11 Unix-Socket und X-Authentifizierungsdatei erstellen" erstellt keine Dateien, sondern definiert nur Variablen?
MrR