Seit geraumer Zeit steht eine Beta Version eines nativen Docker Clients für Mac zur Verfügung, der den Umweg über boot2docker oder sonstige Linux VMs überflüssig macht. Wir nutzen Docker auch, um grafische Anwendungen zu entwickeln. Nun stellt sich die Frage, wie wir eine Anwendung, die einen X11 Server benötigt, von einem nativen Docker Container auf dem Mac darstellen können. In der Vergangenheit haben wir diverse Variationen dieser Aufgabenstellung umgesetzt:

  • Lokale X11 Linux VM, Display auf MacOS oder lokal in der VM
  • Lokale Headless Linux VM, Display auf MacOS
  • Remote Headless Linux VM, Display auf MacOS
  • Remote Headless Linux VM, Display auf Windows 10
  • ...

Nun kommt eine neue Variante dazu:

  • Lokaler native Docker Container, Display auf MacOS

Aus den Erfahrungen der anderen Varianten haben wir gemutmaßt, daß es reichen könnte XQuartz auszuführen und die DISPLAY Umgebungsvariable zu übergeben. Leider wird das mit einem Fehler quittiert, da der Docker Client nicht auf den XQuartz Socket zugreifen kann:

$ docker run --rm -it --net=host -e DISPLAY test/xterm
xterm: Xt error: Can't open display: /private/tmp/com.apple.launchd.TFUw2s0Mer/org.macosforge.xquartz:0  

Auch andere Versuche, den XQuartz Socket als Unix X-Socket über ein Volume Mount einzubinden sind fehlgeschlagen. Also haben wir und für einen Umweg entschieden, bis wir eine bessere Lösung finden oder seitens Docker oder XQuartz entsprechende Änderungen implementiert werden: wir nutzen das Tool socat, um den XQuartz Socket über den X11 Default-Port umzuleiten. Dem Docker Container reicht dann die DISPLAY Umgebungsvariable, um X11 Anwendungen anzeigen zu können. Die Lösung sieht wie folgt aus (Annahme: XQuartz läuft schon):

$ brew install socat
...
$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\" &
$ docker run --rm -it --net=host -e DISPLAY=192.168.178.20:0 test/xterm

Wobei 192.168.178.20 meine aktuelle IP im internen Netz ist.