Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to use -e DISPLAY flag on osx? #8710

Closed
ghost opened this issue Oct 22, 2014 · 115 comments
Closed

how to use -e DISPLAY flag on osx? #8710

ghost opened this issue Oct 22, 2014 · 115 comments

Comments

@ghost
Copy link

ghost commented Oct 22, 2014

I am running boot2docker on OSX 10.10

I have a simple docker image, the dockerfile is:

FROM base/archlinux
RUN pacman -Syu --noconfirm --noprogress 
RUN pacman -S --noprogress --noconfirm firefox

I know that one can use VNC (method: install VNC in image, forward ports, access using VNC on osx etc) and I do not want to use VNC if it's possible to load the GUI application in the container to the host's display using the -e DISPLAY flag. I ran docker run -ti --rm -e DISPLAY -v /tmp/.X11-unix/tmp/.X11-unix arch/firefox and got:

Error: cannot open display: /private/tmp/com.apple.launchd.TDD8jmIe6P/org.macosforge.xquartz:0

Any help is appreciated! Thanks

@jessfraz
Copy link
Contributor

So since boot2docker is running docker in a virtualbox, there are going to be a few extra configurations that need to happen...
I think what you need is to add X11 forwarding to the virtualbox, I will try out some solutions.
I'm a pretty big fan of bind mounting the X11 socket so it would be cool if it was just as easy for boot2docker users :)

@jessfraz
Copy link
Contributor

Yeah so I think VNC is your best option here... you could ssh into the box and enable X11 forwarding as seen here http://oroborosx.sourceforge.net/remotex.html
BUT I hate to say it the awesomeness for bind mounting the X11 sock is really best suited on a linux machine, seeing as it does not require a remote machine (virtualbox), thats really the use case for it. So I am going to close this because we don't plan on supporting something as complicated as bind mounting X11 from osx to a remote server.

@tianon
Copy link
Member

tianon commented Oct 24, 2014

Oh c'mon - where's your sense of adventure? Surely something magical could be done with boot2docker ssh -X ? 😈

@jessfraz
Copy link
Contributor

I mean I am still going to try and find a solution in my freetime for fun ;) , but just to clear up it will be more of a hack than a fully supported docker feature :)

@tianon
Copy link
Member

tianon commented Oct 24, 2014

Hahaha, even the Linux version is truly a hack (but a really cool one).
Until we have "docker run -X", this is all "hack land". :D

@jessfraz
Copy link
Contributor

thats what makes it sooooo cool

@cpuguy83
Copy link
Member

Yeah, I haven't been able to get ssh -X (or -Y) to work on boot2docker at all.
On a debian host I can, of course, get ssh -X to work, but keep getting auth errors trying to start an x11 app in a container :(
Too bad you can't just bind-mount the osx socket in, that'd be awesome.

@jessfraz
Copy link
Contributor

now that would actually be straight up magic

On Fri, Oct 24, 2014 at 5:19 AM, Brian Goff notifications@github.com
wrote:

Yeah, I haven't been able to get ssh -X (or -Y) to work on boot2docker at
all.
On a debian host I can, of course, get ssh -X to work, but keep getting
auth errors trying to start an x11 app in a container :(
To bad you can't just bind-mount the osx socket in, that'd be awesome.


Reply to this email directly or view it on GitHub
#8710 (comment).

@slobo
Copy link

slobo commented Jan 22, 2015

A somewhat crude way to do this:

Start socat to expose local xquartz socket on a TCP port

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

Pass the display to container (assuming virtualbox host is available on 192.168.59.3):

docker run -e DISPLAY=192.168.59.3:0 jess/geary

(This is insecure on public networks, add bind, su and range options to socat to limit access.)

screen shot 2015-01-22 at 2 31 28 pm

@jessfraz
Copy link
Contributor

Wow @slobo

  1. I am so awesomely amazed with what you are trying to do here. And with my image :D :D :D
  2. THIS IS AWESOME!!!!

@thaJeztah
Copy link
Member

Oh, that's really cool!

@saulshanabrook
Copy link

In case anyone else is trying, these are my steps to get @slobo's method to work

brew install socat
brew cask install xquartz
open -a XQuartz

socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
# in another window
docker run -e DISPLAY=192.168.59.3:0 jess/geary

@thiagoeliasr
Copy link

It's awesome. Thanks, @slobo

@Krijger
Copy link

Krijger commented Feb 17, 2015

Note that the $DISPLAY variable is set in the XQuartz shell. In my case, the value was /private/tmp/com.apple.launchd.HxHsgt3DEr/org.macosforge.xquartz:0

@slobo
Copy link

slobo commented Feb 17, 2015

@Krijger did you run the socat command? That will open a TCP port 6000 to read/write from the XQuartz socket. Then you use docker -e DISPLAY=192.168.59.3:0 so that it uses the newly established TCP bridge, as you currently can't bind the raw socket into the VM.

Unless your installation is special, docker -e DISPLAY=192.168.59.3:0 should instruct X clients in docker to look for X server on 192.168.59.3 port 6000, which socat will then forward to XQuartz socket.

@Krijger
Copy link

Krijger commented Feb 17, 2015

@slobo yes, I ran the socat command. Only, I ran that in a shell where DISPLAY was not set, thus socat did not forward to the XQuartz socket. The shell inside of X11 does have this variable.
EDIT: after a system restart this variable is set in the normal shell as well (I installed xquartz with brew cask)

After realizing this I changed my question to you in a statement, but you probably replied directly from email and did not see that. Sorry for that.

@slobo
Copy link

slobo commented Feb 17, 2015

Ah, makes sense. Cheers.

@Krijger
Copy link

Krijger commented Feb 20, 2015

Note that the ip for the display is not $(boot2docker ip), but the address of the vboxnet0 that you can find in ifconfig

vboxnet0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
ether 0a:00:27:00:00:00 
inet 192.168.59.3 netmask 0xffffff00 broadcast 192.168.59.255

@apatawari
Copy link

@slobo
No protocol specified
No protocol specified
Unable to init server: Could not connect: Connection refused

(geary:1): Gtk-WARNING **: cannot open display: 192.168.59.3:0
In my case, I am getting this error. What does this mean exactly?

@apatawari
Copy link

And on the socat screen,
socat[713] E connect(5, LEN=5 AF=1 "0.0", 5): No such file or directory
is the error.

@slobo
Copy link

slobo commented Mar 1, 2015 via email

@apatawari
Copy link

Actually, I realized that after posting the query. But still it gives the same error except no protocol specified is gone. I have attached the Image for the same.
screen shot 2015-03-01 at 10 44 39 am

@slobo
Copy link

slobo commented Mar 1, 2015 via email

@apatawari
Copy link

Yes, In Xterm it does gave me ":0". In terminal app $DISPLAY=0.0, No file
system path, The former error which I got was while ran the socat in
Terminal.app. I did try few things in between, I think that might be the
reason may be it got corrupted. Is their any specific path that I can set
manually or should I try re-installing it.

Yes, In my linux system it did work out with direct docker command just by
mounting the path mounting.

Thanks

Best
Arihant

On Sun, Mar 1, 2015 at 3:03 PM, Slobodan Mišković notifications@github.com
wrote:

Does "echo $DISPLAY" give you ":0" per chance? What if you try it in
Terminal.app, do you get something that looks like file system path? If
so, then try running socat from there.

What we are trying to do is get socat to proxy traffic between TCP port
and
X11 unix socket, so we have to figure out the path to that socket on your
system. On Linux it's often /tmp/.X11-unix/X0, but apple does some funky
stuff with launch daemon to present a socket even when you don't have X11
installed so that they can inform you of missing XQuartz.


Reply to this email directly or view it on GitHub
#8710 (comment).

@slobo
Copy link

slobo commented Mar 2, 2015

Try quitting xquartz and terminal.app, and then starting terminal.app again
and inspect $DISPLAY.

On March 1, 2015 3:35:16 PM Arihant Patawari notifications@github.com wrote:

Yes, In Xterm it does gave me ":0". In terminal app $DISPLAY=0.0, No file
system path, The former error which I got was while ran the socat in
Terminal.app. I did try few things in between, I think that might be the
reason may be it got corrupted. Is their any specific path that I can set
manually or should I try re-installing it.

Yes, In my linux system it did work out with direct docker command just by
mounting the path mounting.

Thanks

Best
Arihant

On Sun, Mar 1, 2015 at 3:03 PM, Slobodan Mišković notifications@github.com
wrote:

Does "echo $DISPLAY" give you ":0" per chance? What if you try it in
Terminal.app, do you get something that looks like file system path? If
so, then try running socat from there.

What we are trying to do is get socat to proxy traffic between TCP port
and
X11 unix socket, so we have to figure out the path to that socket on your
system. On Linux it's often /tmp/.X11-unix/X0, but apple does some funky
stuff with launch daemon to present a socket even when you don't have X11
installed so that they can inform you of missing XQuartz.


Reply to this email directly or view it on GitHub
#8710 (comment).


Reply to this email directly or view it on GitHub:
#8710 (comment)

@apatawari
Copy link

It remains the same $DISPLAY=0.0
It is also possible to set $DISPLAY variable right?

@ksylvan
Copy link

ksylvan commented Jul 14, 2017

This discussion was SUPER useful! After brew cask install xquartz and starting XQuartz:

In the xterm shell, I do this:

$ docker -v
Docker version 17.06.0-ce, build 02c1d87
$ socat TCP-LISTEN:6001,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\" &
[1] 55121
$ docker run -d --rm -e HOME=$(pwd) -e XAUTHORITY=/tmp/xauth \
  -v ~/.Xauthority:/tmp/xauth \
  -e DISPLAY=$(ifconfig en4 | grep 'inet '|awk '{print $2}'):1 \
  --net host -v $(pwd):$(pwd) kayvan/scidvspc

And I have the scidvspc GUI working perfectly. Thank you all!

@kbroughton
Copy link

The magic for me was the above, swap en4 for en13. ifconfig and try one of the ones that thas 'inet ' that is a space, not a number. Then i changed :1 to :0 and voila!

docker run -it -e HOME=$(pwd) -e XAUTHORITY=/tmp/xauth -v 
/Users/kbroughton/.Xauthority:/tmp/xauth -e DISPLAY=$(ifconfig en13 | grep 'inet '|awk '{print 
$2}'):0 --net host -v $(pwd):$(pwd) 3a29 bash

@thom-nic
Copy link

thom-nic commented Feb 5, 2018

I've found using xhost is the easiest way to do this, as long as mounting the unix socket from MacOS is a no-go. It was mentioned above but I wanted to give a more complete example.

First, run XQuartz and open the pref pane. On the Security tab, make sure Allow connections from network clients is enabled. If it was not already checked, you probably need to quit and restart XQuartz.

Now from a mac terminal, run:

open -a XQuartz
xhost + $(hostname)      # this must be called after starting xquartz

docker run --rm -it -e DISPLAY=$(hostname):0 openmicroscopy/octave \
    --eval "graphics_toolkit gnuplot;plot(rand(10));pause"   # this is just an example to show X11 working

If the above doesn't work, try this instead:

IFACE=en4       # change this to whatever your active interface is
IP=$(ifconfig $IFACE | grep inet | awk '$1=="inet" {print $2}')
xhost + $IP       # The '+' is important!

# now run docker as above, substitute `-e DISPLAY=$IP:0`

@jay-hankins
Copy link

Note that, if you have trouble finding the correct IP, docker.for.mac.host.internal is routable from the container networks, so setting it as the DISPLAY variable inside the container works without trying to track down the appropriate interface's IP.

@thom-nic
Copy link

@jay-hankins I tried both DISPLAY=tcp:docker.for.mac.host.internal:0 and DISPLAY=192.168.65.2:0. I suspect the problem lies in what do you use for xhost + $IP on the MacOS side? I tried xhost + 192.168.65.2 but that did not work, I can't open a display from inside the container unless I use the public hostname or IP.

@jay-hankins
Copy link

@thom-nic Sorry, should have clarified; I use the socat method, not the xhost method. I tried a few different things but xhost never seemed to work.

So, here's what works for me on mac OS High Sierra 10.13.3:

$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\" & 
$ docker run -e DISPLAY=docker.for.mac.host.internal:0 jess/tor-browser

image

As I said, docker.for.mac.host.internal is only known to the client containers, so something like xhost +$(docker.for.mac.host.internal) wouldn't work.

@tateman74
Copy link

Hey Guys,

Is there still momentum on this? I realize this thread is nearly 4 years old. But, I can also see extremely valid use cases of serving UIs from containers as does everyone else here.

I'm doing all of the above with Docker 18.0.3, a recent socat version, XQuartz 2.7.11 and OSX 10.13.3.

I've tried @jessfraz's chrome, firefox, slack, etc, etc and all of them are basically unusable.

Piergiorgio Niero's demo of getting GPU support into the container is a pretty cool read:
https://medium.com/@pigiuz/hw-accelerated-gui-apps-on-docker-7fd424fe813e

Seems to get GLXGears going much faster on the GL side. It's obviously super impressive that he's running Blender in a container. I'm guessing I'm not going to be getting a fantastic render of Gangnam Style Doom - (credit Playcanvas guys - you're AWESOME):
https://playcanv.as/b/abx8Go4g/

Am I just an idiot? Don't answer that! 😀
Is anyone seeing near perfect performance from say Firefox or Chrome in containers streaming through X11?

Should I try the xhost route instead? Are we seeing similar results on Windows with Windows containers?

Thanks for any advice.

Steven

@galderz
Copy link

galderz commented Apr 26, 2018

I've tried @jessfraz's chrome, firefox, slack, etc, etc and all of them are basically unusable.

I've tried slack but it's way too slow for me too :(

@tateman74
Copy link

Too bad. I see alot of use cases to be able to run GUIs in containers. Odd to think of how something could be slow that is streaming from one place to another on the same computer. Would that be an X11 problem or a Docker problem? Has anyone tried VNC on local from container to host? Obviously, it would have lag if those were apart. But, does it if they're on the same box?

Steven

@galderz
Copy link

galderz commented Apr 27, 2018

I've tried the socat method and that's way too slow. I'm yet to try xhost

@rocwenlinux
Copy link

Great!
Now i can use PAC manager in macos

docker run -it -e DISPLAY=docker.for.mac.localhost:0 -v /tmp/.X11-unix:/tmp/.X11-unix --rm dresantos/pac pac

@tateman74
Copy link

@rocwenlinux - can you let us know how performance goes there? Everyone else is experiencing dial like performance when mirroring X11 everywhere else.

@rocwenlinux
Copy link

rocwenlinux commented Jun 4, 2018

@tateman74
I just create an ssh connection in PAC manager and use it, it is very fast, no performance issue.

I just follow the steps summarised by saulshanabrook, the only change is host ip address because of macos. i use docker.for.mac.localhost

brew install socat
brew cask install xquartz
open -a XQuartz

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

in another window

docker run -it -e DISPLAY=docker.for.mac.localhost:0 -v /tmp/.X11-unix:/tmp/.X11-unix --rm dresantos/pac pac

My macbook info:
macOS 10.13.4 High Sierra
docker is installed from Docker.dmg
cpu i7

@tateman74
Copy link

Oh I see. You're just mirroring a terminal then? No real GUI applications which is kind of what the thread is all about right?

@rocwenlinux
Copy link

Probably. I am not sure how PAC implement the GUI (perl+GTK?), but its main function is to provide ssh terminal and manage ssh connections, not complex. It isn't a heavy-GUI application.

@titosemi
Copy link

I also gave this a try with the X11 socket approach and it is way too slow. Mostly unusable 😞

@marcellodesales
Copy link

marcellodesales commented Nov 29, 2018

Having this problem over and over and finally found the solution:

  • Install (brew cask install xquartz socat) and logout
  • Close XQuartz
    • You should not see anything running on port 6000
$ lsof -i TCP:6000
$
  • Now socat on the port
$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
  • In a new window, verify if it is opened
$ lsof -i TCP:6000
COMMAND   PID     USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
socat   29298 mdesales    5u  IPv4 0xe21e43ca9d99bf1d      0t0  TCP *:6000 (LISTEN)
  • Then, execute the dockerized UI app with the internal port
$ docker run -e DISPLAY=docker.for.mac.host.internal:0 eyes

screen shot 2018-11-29 at 1 29 37 pm

What I noticed was that XQuartz is opened again

$ lsof -i TCP:6000
COMMAND   PID     USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
socat   29298 mdesales    5u  IPv4 0xe21e43ca9d99bf1d      0t0  TCP *:6000 (LISTEN)
X11.bin 29462 mdesales    8u  IPv6 0xe21e43ca7cdb1135      0t0  TCP *:6000 (LISTEN)

And I just closed it manually after running the app...

TOR

  • docker run -e DISPLAY=docker.for.mac.host.internal:0 jess/tor-browser

screen shot 2018-11-29 at 1 31 56 pm

Eclipse

  • docker run -e DISPLAY=docker.for.mac.host.internal:0 batmat/docker-eclipse

screen shot 2018-11-29 at 1 34 11 pm

@knrt10
Copy link

knrt10 commented Jan 21, 2019

@thom-nic Sorry, should have clarified; I use the socat method, not the xhost method. I tried a few different things but xhost never seemed to work.

So, here's what works for me on mac OS High Sierra 10.13.3:

$ socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\" & 
$ docker run -e DISPLAY=docker.for.mac.host.internal:0 jess/tor-browser

image

As I said, docker.for.mac.host.internal is only known to the client containers, so something like xhost +$(docker.for.mac.host.internal) wouldn't work.

@jay-hankins You saved my day. Was trying to open ns2 for like 1 week. Thanks.

@loretoparisi
Copy link

@marcellodesales thanks for your help, I did all the steps but still getting the error:

ip-192-168-1-52:~ loretoparisi$ lsof -i TCP:6000
COMMAND  PID         USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
X11.bin 1266 loretoparisi   11u  IPv6 0x511017374ef40ddb      0t0  TCP *:6000 (LISTEN)
socat   1601 loretoparisi    5u  IPv4 0x511017373c28c09b      0t0  TCP *:6000 (LISTEN)

docker started as

docker run  -e DISPLAY=docker.for.mac.host.internal:0 --rm -it -v $(pwd):/app facemaskdetect bash

but I'm getting a connection refused from socat:

2020/05/26 21:59:33 socat[1866] E connect(5, LEN=68 AF=1 "/private/tmp/com.apple.launchd.zRvN9T3LeV/org.macosforge.xquartz:0", 68): Connection refused

while the error within docker / open-cv was

: cannot connect to X server docker.for.mac.host.internal:0

I have XQuartz up and running.

@s0rav
Copy link

s0rav commented Jun 23, 2020

my mac complains that it cannot find /dev/snd

@dragon788
Copy link
Contributor

@loretoparisi in newer Docker for Mac releases the hostname is host.docker.internal.

@s0rav what containers are you running? The /dev/snd is a Linux device so you probably need to remove that from your docker run command and it isn't related to the X server either I don't believe.

@loretoparisi
Copy link

loretoparisi commented Jun 23, 2020

@dragon788 thank you! Infact, now I get a different error

docker run  -e DISPLAY=host.docker.internal:0 --rm -it -v $(pwd):/app facemaskdetect bash
$ python facemaskdetect/detector.py -i examples/example_01.png -o cam
[INFO] computing face detections...
No protocol specified
: cannot connect to X server host.docker.internal:0

while if I go for

docker run  -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix --rm -it -v $(pwd):/app facemaskdetect bash
$ python facemaskdetect/detector.py -i examples/example_01.png -o cam
[INFO] computing face detections...
: cannot connect to X server /private/tmp/com.apple.launchd.qIcIi1ayqO/org.macosforge.xquartz:0

[UPDATE]
I finally came out with this solution using the following approach, previously showed, but without using xhost:

export IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
xhost +$IP
xhost +local:docker
docker run --rm -it -e DISPLAY=$IP:0 -e XAUTHORITY=/.Xauthority --net host -v /tmp/.X11-unix:/tmp/.X11-unix -v ~/.Xauthority:/.Xauthority  -v $(pwd):/app facemaskdetect bash
$ python facemaskdetect/detector.py -i examples/example_01.png -o cam
[INFO] computing face detections...
: cannot connect to X server :0

Thank you!

@s0rav
Copy link

s0rav commented Jun 26, 2020

@loretoparisi in newer Docker for Mac releases the hostname is host.docker.internal.

@s0rav what containers are you running? The /dev/snd is a Linux device so you probably need to remove that from your docker run command and it isn't related to the X server either I don't believe.

In my /dev/ directory, /snd/ is not present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests