6

I am new to python and am trying to build a small app. It needs to be a GUI app and I was wanting to containerise it with docker. I am getting the following error and can not find a solution

No protocol specified
No protocol specified
Traceback (most recent call last):
  File "tkinker.py", line 7, in <module>
    tinker = Tk()
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1818, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: couldn't connect to display ":0.0"

It starts locally but wont start in docker. My OS is Xubuntu.

I have created a sample app (below), see run-test.sh https://github.com/jeremysells/test/tree/master/docker-tkinter

Jeremy Sells
  • 61
  • 1
  • 1
  • 5

5 Answers5

4

As described here, you would need an X11 graphic layer.
But since you are already on an '(X)Ubuntu, setting the DISPLAY should be enough:

export DISPLAY=127.0.0.1:0.0

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

Check also XAuthority.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • See also https://github.com/docker/docker/issues/8710#issuecomment-71113263 to expose local xquartz socket on a TCP port. – VonC Sep 12 '16 at 07:34
2

Type xhost + in your terminal. Then

docker run --rm \
    --network=host --privileged \
    -v /dev:/dev \
    -e DISPLAY=$DISPLAY \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -v $HOME/.Xauthority:/root/.Xauthority \
    -it yourimage

worked for me. xhost + disables access control. After which a client can connect from any host.

Dilawar
  • 5,438
  • 9
  • 45
  • 58
  • "Connect" here implies being able to run things like screen captures and keystroke loggers: you really don't want to allow this ability "from any host". – David Maze Jan 03 '20 at 10:57
  • 1
    So, what is the better alternative, @DavidMaze ? – RayLuo Jan 11 '21 at 08:47
1

You'll have to set DISPLAY in the container. You can add it as an argument to the docker run command like this:

docker run -ti -e DISPLAY=$DISPLAY blah-image blah-command

DISPLAY should be set in the Xubuntu shell you are running the command from.

SidJ
  • 669
  • 12
  • 29
  • 1
    Saidly same issue # docker run -ti -e DISPLAY=$DISPLAY tkinter-test:latest Traceback (most recent call last): File "tkinker.py", line 7, in tinker = Tk() File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1818, in __init__ self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) _tkinter.TclError: couldn't connect to display ":0.0" – Jeremy Sells Sep 12 '16 at 07:26
  • Is display set in the shell where you start the command? Are you able to run GUIs from outside of docker? – SidJ Oct 13 '16 at 05:31
  • Yes the display is enabled. When I run `#echo $DISPLAY` it returns ":0.0". I wonder if it has something to do with xauth (http://stackoverflow.com/questions/16296753/can-you-run-gui-apps-in-a-docker-container and http://wiki.ros.org/docker/Tutorials/GUI). I don't have any free time at the moment, so will have to get back to testing this when I do – Jeremy Sells Oct 27 '16 at 06:37
  • Use the IP address of your Linux/UNIX system (not the Docker container). For example, `-e DISPLAY=10.0.0.1:0.0` (replace `10.0.0.1` with the IP address of your Linux/UNIX system). – Dan Anderson Sep 04 '19 at 23:52
0

Derived from the other answer here and inspired by its such comment, my quest ends up with 2 workable solutions. Pick either one you prefer.

  • xhost local:root && docker -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix your_image
  • xhost local:root && docker -e DISPLAY=$DISPLAY --net=host your_image
RayLuo
  • 17,257
  • 6
  • 88
  • 73
0

If you just want it to run on you current screen, it looks like docker has some nice DNS stuff built in for that:

docker run -ti -e DISPLAY=host.docker.internal:0 appname

and for vscode in launch.json add this to the end of your configuration.

"env": {
    "DISPLAY": "host.docker.internal:0"
}

Then, of course, if you are running windows, you need something like xming to receive the X11 packets.

SpiRail
  • 1,377
  • 19
  • 28