1

I'm having problem with opening any X11 window (also plot windows from Python OR ROS scripts) from running Docker containers. In short, I always get similar "cannot open display" errors from different applications.

I am not looking for emulating desktop environment, ssh-forwarding or VNC virtualization.

Platform

Host: Ubuntu 22.04 Docker: Docker Desktop 4.15 Image: Tried firefox, xeyes etc. on plain ubuntu:latest or debian:latest images (e.g. gns3/xeyes, sshipway/xclock). Even I built several from scratch by Dockerfiles.

Run Command

docker run -it --network=host -e DISPLAY -v "/tmp/.X11-unix:/tmp/.X11-unix:rw" <image name>

I've tried also:

  • xhost +local:root, xhost +local:docker, even xhost + before running container
  • --privileged
  • --runtime=runc
  • DISPLAY=127.0.1.1:1 (i.e. <localhost>:<host display>)
  • DISPLAY=unix$DISPLAY

Extra Info

  • Display env var in containers: DISPLAY=:1
  • On host, there is no ~/.Xauthority, instead xauth targets /run/user/1000/gdm/Xauthority
  • I've checked solution 1, solution 2 and solution 3, but still I am missing something.

Can QEMU/KVM virtualization layer be the root of the problem, as it is Docker Desktop (not Docker Engine only)?

STerliakov
  • 4,983
  • 3
  • 15
  • 37
volkbay
  • 11
  • 1

1 Answers1

1

Update Feb.27, 2023: It seems that the magic IP 198.18.0.1 is related to a tun device created by my VPN application, which may handle all the traffic. After removing this device, I could not reproduce the correct result with the following method.


I had the exact settings with you (except for ubuntu 20.04, not 22.04), and tried many solutions for more than a whole day.

Here is what I found in the past day

  1. X server did not listen to TCP by default
  2. --network=host did not work as I thought, neither :1 nor 127.0.0.1:1 solved the problem
  3. when I ping any site (e.g. ping google.com) from within the docker container, it interprets it as 198.18.0.1

I am not clear about the underlying mechanisms, but after trials, I solved the problem by

  1. let X server listen to TCP by default via simply modifying /etc/gdm3/custom.conf with
[security]
DisallowTCP=false

[xdmcp]
ServerArguments=-listen TCP

(assume your Desktop Manager is gdm, which may be the default one as of Ubuntu 17) and restart gdm

  • to check this, use the command nmap localhost to see if 6001 (assume $DISPLAY=:1) or X11 is shown (or any similar commands like netstat -an | grep 6001; ps -ef | grep X can be used to see if Xorg is run with -listen tcp argument)
  1. run a docker container successfully with
xhost +
docker run \
    -it \
    --rm \
    -e DISPLAY=198.18.0.1$DISPLAY \
    xclock

where xclock is a simple image defined by such a Dockerfile

FROM ubuntu:20.04
RUN apt-get update
RUN apt-get install -y x11-apps
RUN apt-get install -y iproute2 \
    curl \
    iputils-ping \
    net-tools
CMD xclock

(the last apt layer was used for previous network debugging, one can omit it), then you should see a GUI clock shown on your monitor.

As for what this 198.18.0.1 mean, what I have known so far is that

  1. it is contained in the output of ifconfig
  2. it is the prefix 198.18.0 is contained in the output of ping called from within the docker container

Therefore, I guess it relates to some network interface that served as a bridge between the host and the docker container. However, this guess seems to conflict with my understanding of the host mode (and hence I remove the --network=host).

Furthermore, I finally did not map the UNIX socket file /tmp/.X11-unix as I found it did not affect the result. I am not sure if then the connection is fully transmitted through TCP instead of UNIX socket file.

Remember to xhost - after trials. Disabling the firewall will be unnecessary, so just keep it open via sudo ufw enable. Again, I am unsure about the mechanism, or its safety issues.

I hurried to post this answer soon after I solve my issue, and might modify it later if any new discoveries pop out or mistakes exist. Hope any expert could correct my flaws and questions.

Jimmy
  • 11
  • 2
  • 1
    Good effort @Jimmy, I can also confirm this is a TCP-listening issue. Considering the update (on 27th Feb), your workaround is not very satisfying to me, though. All in all, I gave up and went for Docker Engine, instead. It works as it should, even for 3D visualization apps. – volkbay Mar 01 '23 at 13:47